ActivityManagerService.java revision 7bc33c0d252b190af8258c827de8a8a5382210db
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    /**
1079     * If true, we are running under a test environment so will sample PSS from processes
1080     * much more rapidly to try to collect better data when the tests are rapidly
1081     * running through apps.
1082     */
1083    boolean mTestPssMode = false;
1084
1085    String mDebugApp = null;
1086    boolean mWaitForDebugger = false;
1087    boolean mDebugTransient = false;
1088    String mOrigDebugApp = null;
1089    boolean mOrigWaitForDebugger = false;
1090    boolean mAlwaysFinishActivities = false;
1091    IActivityController mController = null;
1092    String mProfileApp = null;
1093    ProcessRecord mProfileProc = null;
1094    String mProfileFile;
1095    ParcelFileDescriptor mProfileFd;
1096    int mSamplingInterval = 0;
1097    boolean mAutoStopProfiler = false;
1098    int mProfileType = 0;
1099    String mOpenGlTraceApp = null;
1100
1101    final long[] mTmpLong = new long[1];
1102
1103    static class ProcessChangeItem {
1104        static final int CHANGE_ACTIVITIES = 1<<0;
1105        static final int CHANGE_PROCESS_STATE = 1<<1;
1106        int changes;
1107        int uid;
1108        int pid;
1109        int processState;
1110        boolean foregroundActivities;
1111    }
1112
1113    final RemoteCallbackList<IProcessObserver> mProcessObservers
1114            = new RemoteCallbackList<IProcessObserver>();
1115    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1116
1117    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1118            = new ArrayList<ProcessChangeItem>();
1119    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1120            = new ArrayList<ProcessChangeItem>();
1121
1122    /**
1123     * Runtime CPU use collection thread.  This object's lock is used to
1124     * perform synchronization with the thread (notifying it to run).
1125     */
1126    final Thread mProcessCpuThread;
1127
1128    /**
1129     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1130     * Must acquire this object's lock when accessing it.
1131     * NOTE: this lock will be held while doing long operations (trawling
1132     * through all processes in /proc), so it should never be acquired by
1133     * any critical paths such as when holding the main activity manager lock.
1134     */
1135    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1136            MONITOR_THREAD_CPU_USAGE);
1137    final AtomicLong mLastCpuTime = new AtomicLong(0);
1138    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1139
1140    long mLastWriteTime = 0;
1141
1142    /**
1143     * Used to retain an update lock when the foreground activity is in
1144     * immersive mode.
1145     */
1146    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1147
1148    /**
1149     * Set to true after the system has finished booting.
1150     */
1151    boolean mBooted = false;
1152
1153    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1154    int mProcessLimitOverride = -1;
1155
1156    WindowManagerService mWindowManager;
1157
1158    final ActivityThread mSystemThread;
1159
1160    // Holds the current foreground user's id
1161    int mCurrentUserId = 0;
1162    // Holds the target user's id during a user switch
1163    int mTargetUserId = UserHandle.USER_NULL;
1164    // If there are multiple profiles for the current user, their ids are here
1165    // Currently only the primary user can have managed profiles
1166    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1167
1168    /**
1169     * Mapping from each known user ID to the profile group ID it is associated with.
1170     */
1171    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1172
1173    private UserManagerService mUserManager;
1174
1175    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1176        final ProcessRecord mApp;
1177        final int mPid;
1178        final IApplicationThread mAppThread;
1179
1180        AppDeathRecipient(ProcessRecord app, int pid,
1181                IApplicationThread thread) {
1182            if (localLOGV) Slog.v(
1183                TAG, "New death recipient " + this
1184                + " for thread " + thread.asBinder());
1185            mApp = app;
1186            mPid = pid;
1187            mAppThread = thread;
1188        }
1189
1190        @Override
1191        public void binderDied() {
1192            if (localLOGV) Slog.v(
1193                TAG, "Death received in " + this
1194                + " for thread " + mAppThread.asBinder());
1195            synchronized(ActivityManagerService.this) {
1196                appDiedLocked(mApp, mPid, mAppThread);
1197            }
1198        }
1199    }
1200
1201    static final int SHOW_ERROR_MSG = 1;
1202    static final int SHOW_NOT_RESPONDING_MSG = 2;
1203    static final int SHOW_FACTORY_ERROR_MSG = 3;
1204    static final int UPDATE_CONFIGURATION_MSG = 4;
1205    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1206    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1207    static final int SERVICE_TIMEOUT_MSG = 12;
1208    static final int UPDATE_TIME_ZONE = 13;
1209    static final int SHOW_UID_ERROR_MSG = 14;
1210    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1211    static final int PROC_START_TIMEOUT_MSG = 20;
1212    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1213    static final int KILL_APPLICATION_MSG = 22;
1214    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1215    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1216    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1217    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1218    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1219    static final int CLEAR_DNS_CACHE_MSG = 28;
1220    static final int UPDATE_HTTP_PROXY_MSG = 29;
1221    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1222    static final int DISPATCH_PROCESSES_CHANGED = 31;
1223    static final int DISPATCH_PROCESS_DIED = 32;
1224    static final int REPORT_MEM_USAGE_MSG = 33;
1225    static final int REPORT_USER_SWITCH_MSG = 34;
1226    static final int CONTINUE_USER_SWITCH_MSG = 35;
1227    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1228    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1229    static final int PERSIST_URI_GRANTS_MSG = 38;
1230    static final int REQUEST_ALL_PSS_MSG = 39;
1231    static final int START_PROFILES_MSG = 40;
1232    static final int UPDATE_TIME = 41;
1233    static final int SYSTEM_USER_START_MSG = 42;
1234    static final int SYSTEM_USER_CURRENT_MSG = 43;
1235    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1236    static final int FINISH_BOOTING_MSG = 45;
1237    static final int START_USER_SWITCH_MSG = 46;
1238    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1239    static final int DISMISS_DIALOG_MSG = 48;
1240    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1241
1242    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1243    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1244    static final int FIRST_COMPAT_MODE_MSG = 300;
1245    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1246
1247    CompatModeDialog mCompatModeDialog;
1248    long mLastMemUsageReportTime = 0;
1249
1250    /**
1251     * Flag whether the current user is a "monkey", i.e. whether
1252     * the UI is driven by a UI automation tool.
1253     */
1254    private boolean mUserIsMonkey;
1255
1256    /** Flag whether the device has a Recents UI */
1257    boolean mHasRecents;
1258
1259    /** The dimensions of the thumbnails in the Recents UI. */
1260    int mThumbnailWidth;
1261    int mThumbnailHeight;
1262
1263    final ServiceThread mHandlerThread;
1264    final MainHandler mHandler;
1265
1266    final class MainHandler extends Handler {
1267        public MainHandler(Looper looper) {
1268            super(looper, null, true);
1269        }
1270
1271        @Override
1272        public void handleMessage(Message msg) {
1273            switch (msg.what) {
1274            case SHOW_ERROR_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1277                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1278                synchronized (ActivityManagerService.this) {
1279                    ProcessRecord proc = (ProcessRecord)data.get("app");
1280                    AppErrorResult res = (AppErrorResult) data.get("result");
1281                    if (proc != null && proc.crashDialog != null) {
1282                        Slog.e(TAG, "App already has crash dialog: " + proc);
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                        return;
1287                    }
1288                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1289                            >= Process.FIRST_APPLICATION_UID
1290                            && proc.pid != MY_PID);
1291                    for (int userId : mCurrentProfileIds) {
1292                        isBackground &= (proc.userId != userId);
1293                    }
1294                    if (isBackground && !showBackground) {
1295                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1296                        if (res != null) {
1297                            res.set(0);
1298                        }
1299                        return;
1300                    }
1301                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1302                        Dialog d = new AppErrorDialog(mContext,
1303                                ActivityManagerService.this, res, proc);
1304                        d.show();
1305                        proc.crashDialog = d;
1306                    } else {
1307                        // The device is asleep, so just pretend that the user
1308                        // saw a crash dialog and hit "force quit".
1309                        if (res != null) {
1310                            res.set(0);
1311                        }
1312                    }
1313                }
1314
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_NOT_RESPONDING_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                    ProcessRecord proc = (ProcessRecord)data.get("app");
1321                    if (proc != null && proc.anrDialog != null) {
1322                        Slog.e(TAG, "App already has anr dialog: " + proc);
1323                        return;
1324                    }
1325
1326                    Intent intent = new Intent("android.intent.action.ANR");
1327                    if (!mProcessesReady) {
1328                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1329                                | Intent.FLAG_RECEIVER_FOREGROUND);
1330                    }
1331                    broadcastIntentLocked(null, null, intent,
1332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1333                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1334
1335                    if (mShowDialogs) {
1336                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1337                                mContext, proc, (ActivityRecord)data.get("activity"),
1338                                msg.arg1 != 0);
1339                        d.show();
1340                        proc.anrDialog = d;
1341                    } else {
1342                        // Just kill the app if there is no dialog to be shown.
1343                        killAppAtUsersRequest(proc, null);
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1350                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord proc = (ProcessRecord) data.get("app");
1353                    if (proc == null) {
1354                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1355                        break;
1356                    }
1357                    if (proc.crashDialog != null) {
1358                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1359                        return;
1360                    }
1361                    AppErrorResult res = (AppErrorResult) data.get("result");
1362                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1363                        Dialog d = new StrictModeViolationDialog(mContext,
1364                                ActivityManagerService.this, res, proc);
1365                        d.show();
1366                        proc.crashDialog = d;
1367                    } else {
1368                        // The device is asleep, so just pretend that the user
1369                        // saw a crash dialog and hit "force quit".
1370                        res.set(0);
1371                    }
1372                }
1373                ensureBootCompleted();
1374            } break;
1375            case SHOW_FACTORY_ERROR_MSG: {
1376                Dialog d = new FactoryErrorDialog(
1377                    mContext, msg.getData().getCharSequence("msg"));
1378                d.show();
1379                ensureBootCompleted();
1380            } break;
1381            case UPDATE_CONFIGURATION_MSG: {
1382                final ContentResolver resolver = mContext.getContentResolver();
1383                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1384            } break;
1385            case GC_BACKGROUND_PROCESSES_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    performAppGcsIfAppropriateLocked();
1388                }
1389            } break;
1390            case WAIT_FOR_DEBUGGER_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord app = (ProcessRecord)msg.obj;
1393                    if (msg.arg1 != 0) {
1394                        if (!app.waitedForDebugger) {
1395                            Dialog d = new AppWaitingForDebuggerDialog(
1396                                    ActivityManagerService.this,
1397                                    mContext, app);
1398                            app.waitDialog = d;
1399                            app.waitedForDebugger = true;
1400                            d.show();
1401                        }
1402                    } else {
1403                        if (app.waitDialog != null) {
1404                            app.waitDialog.dismiss();
1405                            app.waitDialog = null;
1406                        }
1407                    }
1408                }
1409            } break;
1410            case SERVICE_TIMEOUT_MSG: {
1411                if (mDidDexOpt) {
1412                    mDidDexOpt = false;
1413                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1414                    nmsg.obj = msg.obj;
1415                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1416                    return;
1417                }
1418                mServices.serviceTimeout((ProcessRecord)msg.obj);
1419            } break;
1420            case UPDATE_TIME_ZONE: {
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.updateTimeZone();
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case CLEAR_DNS_CACHE_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.clearDnsCache();
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case UPDATE_HTTP_PROXY_MSG: {
1449                ProxyInfo proxy = (ProxyInfo)msg.obj;
1450                String host = "";
1451                String port = "";
1452                String exclList = "";
1453                Uri pacFileUrl = Uri.EMPTY;
1454                if (proxy != null) {
1455                    host = proxy.getHost();
1456                    port = Integer.toString(proxy.getPort());
1457                    exclList = proxy.getExclusionListAsString();
1458                    pacFileUrl = proxy.getPacFileUrl();
1459                }
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to update http proxy for: " +
1468                                        r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case SHOW_UID_ERROR_MSG: {
1475                if (mShowDialogs) {
1476                    AlertDialog d = new BaseErrorDialog(mContext);
1477                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1478                    d.setCancelable(false);
1479                    d.setTitle(mContext.getText(R.string.android_system_label));
1480                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1481                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1482                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1483                    d.show();
1484                }
1485            } break;
1486            case SHOW_FINGERPRINT_ERROR_MSG: {
1487                if (mShowDialogs) {
1488                    AlertDialog d = new BaseErrorDialog(mContext);
1489                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1490                    d.setCancelable(false);
1491                    d.setTitle(mContext.getText(R.string.android_system_label));
1492                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1493                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1494                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1495                    d.show();
1496                }
1497            } break;
1498            case PROC_START_TIMEOUT_MSG: {
1499                if (mDidDexOpt) {
1500                    mDidDexOpt = false;
1501                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1502                    nmsg.obj = msg.obj;
1503                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1504                    return;
1505                }
1506                ProcessRecord app = (ProcessRecord)msg.obj;
1507                synchronized (ActivityManagerService.this) {
1508                    processStartTimedOutLocked(app);
1509                }
1510            } break;
1511            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1514                }
1515            } break;
1516            case KILL_APPLICATION_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    int appid = msg.arg1;
1519                    boolean restart = (msg.arg2 == 1);
1520                    Bundle bundle = (Bundle)msg.obj;
1521                    String pkg = bundle.getString("pkg");
1522                    String reason = bundle.getString("reason");
1523                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1524                            false, UserHandle.USER_ALL, reason);
1525                }
1526            } break;
1527            case FINALIZE_PENDING_INTENT_MSG: {
1528                ((PendingIntentRecord)msg.obj).completeFinalize();
1529            } break;
1530            case POST_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535
1536                ActivityRecord root = (ActivityRecord)msg.obj;
1537                ProcessRecord process = root.app;
1538                if (process == null) {
1539                    return;
1540                }
1541
1542                try {
1543                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1544                    String text = mContext.getString(R.string.heavy_weight_notification,
1545                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1546                    Notification notification = new Notification();
1547                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1548                    notification.when = 0;
1549                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1550                    notification.tickerText = text;
1551                    notification.defaults = 0; // please be quiet
1552                    notification.sound = null;
1553                    notification.vibrate = null;
1554                    notification.color = mContext.getResources().getColor(
1555                            com.android.internal.R.color.system_notification_accent_color);
1556                    notification.setLatestEventInfo(context, text,
1557                            mContext.getText(R.string.heavy_weight_notification_detail),
1558                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1559                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1560                                    new UserHandle(root.userId)));
1561
1562                    try {
1563                        int[] outId = new int[1];
1564                        inm.enqueueNotificationWithTag("android", "android", null,
1565                                R.string.heavy_weight_notification,
1566                                notification, outId, root.userId);
1567                    } catch (RuntimeException e) {
1568                        Slog.w(ActivityManagerService.TAG,
1569                                "Error showing notification for heavy-weight app", e);
1570                    } catch (RemoteException e) {
1571                    }
1572                } catch (NameNotFoundException e) {
1573                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1574                }
1575            } break;
1576            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1577                INotificationManager inm = NotificationManager.getService();
1578                if (inm == null) {
1579                    return;
1580                }
1581                try {
1582                    inm.cancelNotificationWithTag("android", null,
1583                            R.string.heavy_weight_notification,  msg.arg1);
1584                } catch (RuntimeException e) {
1585                    Slog.w(ActivityManagerService.TAG,
1586                            "Error canceling notification for service", e);
1587                } catch (RemoteException e) {
1588                }
1589            } break;
1590            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1591                synchronized (ActivityManagerService.this) {
1592                    checkExcessivePowerUsageLocked(true);
1593                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1594                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1595                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1596                }
1597            } break;
1598            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ActivityRecord ar = (ActivityRecord)msg.obj;
1601                    if (mCompatModeDialog != null) {
1602                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1603                                ar.info.applicationInfo.packageName)) {
1604                            return;
1605                        }
1606                        mCompatModeDialog.dismiss();
1607                        mCompatModeDialog = null;
1608                    }
1609                    if (ar != null && false) {
1610                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1611                                ar.packageName)) {
1612                            int mode = mCompatModePackages.computeCompatModeLocked(
1613                                    ar.info.applicationInfo);
1614                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1615                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1616                                mCompatModeDialog = new CompatModeDialog(
1617                                        ActivityManagerService.this, mContext,
1618                                        ar.info.applicationInfo);
1619                                mCompatModeDialog.show();
1620                            }
1621                        }
1622                    }
1623                }
1624                break;
1625            }
1626            case DISPATCH_PROCESSES_CHANGED: {
1627                dispatchProcessesChanged();
1628                break;
1629            }
1630            case DISPATCH_PROCESS_DIED: {
1631                final int pid = msg.arg1;
1632                final int uid = msg.arg2;
1633                dispatchProcessDied(pid, uid);
1634                break;
1635            }
1636            case REPORT_MEM_USAGE_MSG: {
1637                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1638                Thread thread = new Thread() {
1639                    @Override public void run() {
1640                        reportMemUsage(memInfos);
1641                    }
1642                };
1643                thread.start();
1644                break;
1645            }
1646            case START_USER_SWITCH_MSG: {
1647                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1648                break;
1649            }
1650            case REPORT_USER_SWITCH_MSG: {
1651                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case CONTINUE_USER_SWITCH_MSG: {
1655                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case USER_SWITCH_TIMEOUT_MSG: {
1659                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case IMMERSIVE_MODE_LOCK_MSG: {
1663                final boolean nextState = (msg.arg1 != 0);
1664                if (mUpdateLock.isHeld() != nextState) {
1665                    if (DEBUG_IMMERSIVE) {
1666                        final ActivityRecord r = (ActivityRecord) msg.obj;
1667                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1668                    }
1669                    if (nextState) {
1670                        mUpdateLock.acquire();
1671                    } else {
1672                        mUpdateLock.release();
1673                    }
1674                }
1675                break;
1676            }
1677            case PERSIST_URI_GRANTS_MSG: {
1678                writeGrantedUriPermissions();
1679                break;
1680            }
1681            case REQUEST_ALL_PSS_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1684                }
1685                break;
1686            }
1687            case START_PROFILES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    startProfilesLocked();
1690                }
1691                break;
1692            }
1693            case UPDATE_TIME: {
1694                synchronized (ActivityManagerService.this) {
1695                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1696                        ProcessRecord r = mLruProcesses.get(i);
1697                        if (r.thread != null) {
1698                            try {
1699                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1700                            } catch (RemoteException ex) {
1701                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1702                            }
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case SYSTEM_USER_START_MSG: {
1709                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.startUser(msg.arg1);
1712                break;
1713            }
1714            case SYSTEM_USER_CURRENT_MSG: {
1715                mBatteryStatsService.noteEvent(
1716                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1717                        Integer.toString(msg.arg2), msg.arg2);
1718                mBatteryStatsService.noteEvent(
1719                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1720                        Integer.toString(msg.arg1), msg.arg1);
1721                mSystemServiceManager.switchUser(msg.arg1);
1722                break;
1723            }
1724            case ENTER_ANIMATION_COMPLETE_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1727                    if (r != null && r.app != null && r.app.thread != null) {
1728                        try {
1729                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1730                        } catch (RemoteException e) {
1731                        }
1732                    }
1733                }
1734                break;
1735            }
1736            case FINISH_BOOTING_MSG: {
1737                if (msg.arg1 != 0) {
1738                    finishBooting();
1739                }
1740                if (msg.arg2 != 0) {
1741                    enableScreenAfterBoot();
1742                }
1743                break;
1744            }
1745            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1746                try {
1747                    Locale l = (Locale) msg.obj;
1748                    IBinder service = ServiceManager.getService("mount");
1749                    IMountService mountService = IMountService.Stub.asInterface(service);
1750                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1751                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1752                } catch (RemoteException e) {
1753                    Log.e(TAG, "Error storing locale for decryption UI", e);
1754                }
1755                break;
1756            }
1757            case DISMISS_DIALOG_MSG: {
1758                final Dialog d = (Dialog) msg.obj;
1759                d.dismiss();
1760                break;
1761            }
1762            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    int i = mTaskStackListeners.beginBroadcast();
1765                    while (i > 0) {
1766                        i--;
1767                        try {
1768                            // Make a one-way callback to the listener
1769                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1770                        } catch (RemoteException e){
1771                            // Handled by the RemoteCallbackList
1772                        }
1773                    }
1774                    mTaskStackListeners.finishBroadcast();
1775                }
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                long start = SystemClock.uptimeMillis();
1790                MemInfoReader memInfo = null;
1791                synchronized (ActivityManagerService.this) {
1792                    if (mFullPssPending) {
1793                        mFullPssPending = false;
1794                        memInfo = new MemInfoReader();
1795                    }
1796                }
1797                if (memInfo != null) {
1798                    updateCpuStatsNow();
1799                    long nativeTotalPss = 0;
1800                    synchronized (mProcessCpuTracker) {
1801                        final int N = mProcessCpuTracker.countStats();
1802                        for (int j=0; j<N; j++) {
1803                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1804                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1805                                // This is definitely an application process; skip it.
1806                                continue;
1807                            }
1808                            synchronized (mPidsSelfLocked) {
1809                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1810                                    // This is one of our own processes; skip it.
1811                                    continue;
1812                                }
1813                            }
1814                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1815                        }
1816                    }
1817                    memInfo.readMemInfo();
1818                    synchronized (ActivityManagerService.this) {
1819                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1820                                + (SystemClock.uptimeMillis()-start) + "ms");
1821                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1822                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1823                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1824                    }
1825                }
1826
1827                int num = 0;
1828                long[] tmp = new long[1];
1829                do {
1830                    ProcessRecord proc;
1831                    int procState;
1832                    int pid;
1833                    long lastPssTime;
1834                    synchronized (ActivityManagerService.this) {
1835                        if (mPendingPssProcesses.size() <= 0) {
1836                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1837                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1838                            mPendingPssProcesses.clear();
1839                            return;
1840                        }
1841                        proc = mPendingPssProcesses.remove(0);
1842                        procState = proc.pssProcState;
1843                        lastPssTime = proc.lastPssTime;
1844                        if (proc.thread != null && procState == proc.setProcState
1845                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1846                                        < SystemClock.uptimeMillis()) {
1847                            pid = proc.pid;
1848                        } else {
1849                            proc = null;
1850                            pid = 0;
1851                        }
1852                    }
1853                    if (proc != null) {
1854                        long pss = Debug.getPss(pid, tmp, null);
1855                        synchronized (ActivityManagerService.this) {
1856                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1857                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1858                                num++;
1859                                recordPssSample(proc, procState, pss, tmp[0],
1860                                        SystemClock.uptimeMillis());
1861                            }
1862                        }
1863                    }
1864                } while (true);
1865            }
1866            }
1867        }
1868    };
1869
1870    public void setSystemProcess() {
1871        try {
1872            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1873            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1874            ServiceManager.addService("meminfo", new MemBinder(this));
1875            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1876            ServiceManager.addService("dbinfo", new DbBinder(this));
1877            if (MONITOR_CPU_USAGE) {
1878                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1879            }
1880            ServiceManager.addService("permission", new PermissionController(this));
1881
1882            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1883                    "android", STOCK_PM_FLAGS);
1884            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1885
1886            synchronized (this) {
1887                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1888                app.persistent = true;
1889                app.pid = MY_PID;
1890                app.maxAdj = ProcessList.SYSTEM_ADJ;
1891                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1892                mProcessNames.put(app.processName, app.uid, app);
1893                synchronized (mPidsSelfLocked) {
1894                    mPidsSelfLocked.put(app.pid, app);
1895                }
1896                updateLruProcessLocked(app, false, null);
1897                updateOomAdjLocked();
1898            }
1899        } catch (PackageManager.NameNotFoundException e) {
1900            throw new RuntimeException(
1901                    "Unable to find android system package", e);
1902        }
1903    }
1904
1905    public void setWindowManager(WindowManagerService wm) {
1906        mWindowManager = wm;
1907        mStackSupervisor.setWindowManager(wm);
1908    }
1909
1910    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1911        mUsageStatsService = usageStatsManager;
1912    }
1913
1914    public void startObservingNativeCrashes() {
1915        final NativeCrashListener ncl = new NativeCrashListener(this);
1916        ncl.start();
1917    }
1918
1919    public IAppOpsService getAppOpsService() {
1920        return mAppOpsService;
1921    }
1922
1923    static class MemBinder extends Binder {
1924        ActivityManagerService mActivityManagerService;
1925        MemBinder(ActivityManagerService activityManagerService) {
1926            mActivityManagerService = activityManagerService;
1927        }
1928
1929        @Override
1930        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1931            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1932                    != PackageManager.PERMISSION_GRANTED) {
1933                pw.println("Permission Denial: can't dump meminfo from from pid="
1934                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1935                        + " without permission " + android.Manifest.permission.DUMP);
1936                return;
1937            }
1938
1939            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1940        }
1941    }
1942
1943    static class GraphicsBinder extends Binder {
1944        ActivityManagerService mActivityManagerService;
1945        GraphicsBinder(ActivityManagerService activityManagerService) {
1946            mActivityManagerService = activityManagerService;
1947        }
1948
1949        @Override
1950        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1951            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1952                    != PackageManager.PERMISSION_GRANTED) {
1953                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1954                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1955                        + " without permission " + android.Manifest.permission.DUMP);
1956                return;
1957            }
1958
1959            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1960        }
1961    }
1962
1963    static class DbBinder extends Binder {
1964        ActivityManagerService mActivityManagerService;
1965        DbBinder(ActivityManagerService activityManagerService) {
1966            mActivityManagerService = activityManagerService;
1967        }
1968
1969        @Override
1970        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1971            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1972                    != PackageManager.PERMISSION_GRANTED) {
1973                pw.println("Permission Denial: can't dump dbinfo from from pid="
1974                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1975                        + " without permission " + android.Manifest.permission.DUMP);
1976                return;
1977            }
1978
1979            mActivityManagerService.dumpDbInfo(fd, pw, args);
1980        }
1981    }
1982
1983    static class CpuBinder extends Binder {
1984        ActivityManagerService mActivityManagerService;
1985        CpuBinder(ActivityManagerService activityManagerService) {
1986            mActivityManagerService = activityManagerService;
1987        }
1988
1989        @Override
1990        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1991            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1992                    != PackageManager.PERMISSION_GRANTED) {
1993                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1994                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1995                        + " without permission " + android.Manifest.permission.DUMP);
1996                return;
1997            }
1998
1999            synchronized (mActivityManagerService.mProcessCpuTracker) {
2000                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2001                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2002                        SystemClock.uptimeMillis()));
2003            }
2004        }
2005    }
2006
2007    public static final class Lifecycle extends SystemService {
2008        private final ActivityManagerService mService;
2009
2010        public Lifecycle(Context context) {
2011            super(context);
2012            mService = new ActivityManagerService(context);
2013        }
2014
2015        @Override
2016        public void onStart() {
2017            mService.start();
2018        }
2019
2020        public ActivityManagerService getService() {
2021            return mService;
2022        }
2023    }
2024
2025    // Note: This method is invoked on the main thread but may need to attach various
2026    // handlers to other threads.  So take care to be explicit about the looper.
2027    public ActivityManagerService(Context systemContext) {
2028        mContext = systemContext;
2029        mFactoryTest = FactoryTest.getMode();
2030        mSystemThread = ActivityThread.currentActivityThread();
2031
2032        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2033
2034        mHandlerThread = new ServiceThread(TAG,
2035                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2036        mHandlerThread.start();
2037        mHandler = new MainHandler(mHandlerThread.getLooper());
2038
2039        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "foreground", BROADCAST_FG_TIMEOUT, false);
2041        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2042                "background", BROADCAST_BG_TIMEOUT, true);
2043        mBroadcastQueues[0] = mFgBroadcastQueue;
2044        mBroadcastQueues[1] = mBgBroadcastQueue;
2045
2046        mServices = new ActiveServices(this);
2047        mProviderMap = new ProviderMap(this);
2048
2049        // TODO: Move creation of battery stats service outside of activity manager service.
2050        File dataDir = Environment.getDataDirectory();
2051        File systemDir = new File(dataDir, "system");
2052        systemDir.mkdirs();
2053        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2054        mBatteryStatsService.getActiveStatistics().readLocked();
2055        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2056        mOnBattery = DEBUG_POWER ? true
2057                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2058        mBatteryStatsService.getActiveStatistics().setCallback(this);
2059
2060        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2061
2062        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2063
2064        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2065
2066        // User 0 is the first and only user that runs at boot.
2067        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2068        mUserLru.add(Integer.valueOf(0));
2069        updateStartedUserArrayLocked();
2070
2071        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2072            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2073
2074        mConfiguration.setToDefaults();
2075        mConfiguration.setLocale(Locale.getDefault());
2076
2077        mConfigurationSeq = mConfiguration.seq = 1;
2078        mProcessCpuTracker.init();
2079
2080        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2081        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2082        mStackSupervisor = new ActivityStackSupervisor(this);
2083        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2084
2085        mProcessCpuThread = new Thread("CpuTracker") {
2086            @Override
2087            public void run() {
2088                while (true) {
2089                    try {
2090                        try {
2091                            synchronized(this) {
2092                                final long now = SystemClock.uptimeMillis();
2093                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2094                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2095                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2096                                //        + ", write delay=" + nextWriteDelay);
2097                                if (nextWriteDelay < nextCpuDelay) {
2098                                    nextCpuDelay = nextWriteDelay;
2099                                }
2100                                if (nextCpuDelay > 0) {
2101                                    mProcessCpuMutexFree.set(true);
2102                                    this.wait(nextCpuDelay);
2103                                }
2104                            }
2105                        } catch (InterruptedException e) {
2106                        }
2107                        updateCpuStatsNow();
2108                    } catch (Exception e) {
2109                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2110                    }
2111                }
2112            }
2113        };
2114
2115        Watchdog.getInstance().addMonitor(this);
2116        Watchdog.getInstance().addThread(mHandler);
2117    }
2118
2119    public void setSystemServiceManager(SystemServiceManager mgr) {
2120        mSystemServiceManager = mgr;
2121    }
2122
2123    public void setInstaller(Installer installer) {
2124        mInstaller = installer;
2125    }
2126
2127    private void start() {
2128        Process.removeAllProcessGroups();
2129        mProcessCpuThread.start();
2130
2131        mBatteryStatsService.publish(mContext);
2132        mAppOpsService.publish(mContext);
2133        Slog.d("AppOps", "AppOpsService published");
2134        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2135    }
2136
2137    public void initPowerManagement() {
2138        mStackSupervisor.initPowerManagement();
2139        mBatteryStatsService.initPowerManagement();
2140    }
2141
2142    @Override
2143    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2144            throws RemoteException {
2145        if (code == SYSPROPS_TRANSACTION) {
2146            // We need to tell all apps about the system property change.
2147            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2148            synchronized(this) {
2149                final int NP = mProcessNames.getMap().size();
2150                for (int ip=0; ip<NP; ip++) {
2151                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2152                    final int NA = apps.size();
2153                    for (int ia=0; ia<NA; ia++) {
2154                        ProcessRecord app = apps.valueAt(ia);
2155                        if (app.thread != null) {
2156                            procs.add(app.thread.asBinder());
2157                        }
2158                    }
2159                }
2160            }
2161
2162            int N = procs.size();
2163            for (int i=0; i<N; i++) {
2164                Parcel data2 = Parcel.obtain();
2165                try {
2166                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2167                } catch (RemoteException e) {
2168                }
2169                data2.recycle();
2170            }
2171        }
2172        try {
2173            return super.onTransact(code, data, reply, flags);
2174        } catch (RuntimeException e) {
2175            // The activity manager only throws security exceptions, so let's
2176            // log all others.
2177            if (!(e instanceof SecurityException)) {
2178                Slog.wtf(TAG, "Activity Manager Crash", e);
2179            }
2180            throw e;
2181        }
2182    }
2183
2184    void updateCpuStats() {
2185        final long now = SystemClock.uptimeMillis();
2186        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2187            return;
2188        }
2189        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2190            synchronized (mProcessCpuThread) {
2191                mProcessCpuThread.notify();
2192            }
2193        }
2194    }
2195
2196    void updateCpuStatsNow() {
2197        synchronized (mProcessCpuTracker) {
2198            mProcessCpuMutexFree.set(false);
2199            final long now = SystemClock.uptimeMillis();
2200            boolean haveNewCpuStats = false;
2201
2202            if (MONITOR_CPU_USAGE &&
2203                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2204                mLastCpuTime.set(now);
2205                haveNewCpuStats = true;
2206                mProcessCpuTracker.update();
2207                //Slog.i(TAG, mProcessCpu.printCurrentState());
2208                //Slog.i(TAG, "Total CPU usage: "
2209                //        + mProcessCpu.getTotalCpuPercent() + "%");
2210
2211                // Slog the cpu usage if the property is set.
2212                if ("true".equals(SystemProperties.get("events.cpu"))) {
2213                    int user = mProcessCpuTracker.getLastUserTime();
2214                    int system = mProcessCpuTracker.getLastSystemTime();
2215                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2216                    int irq = mProcessCpuTracker.getLastIrqTime();
2217                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2218                    int idle = mProcessCpuTracker.getLastIdleTime();
2219
2220                    int total = user + system + iowait + irq + softIrq + idle;
2221                    if (total == 0) total = 1;
2222
2223                    EventLog.writeEvent(EventLogTags.CPU,
2224                            ((user+system+iowait+irq+softIrq) * 100) / total,
2225                            (user * 100) / total,
2226                            (system * 100) / total,
2227                            (iowait * 100) / total,
2228                            (irq * 100) / total,
2229                            (softIrq * 100) / total);
2230                }
2231            }
2232
2233            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2234            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2235            synchronized(bstats) {
2236                synchronized(mPidsSelfLocked) {
2237                    if (haveNewCpuStats) {
2238                        if (mOnBattery) {
2239                            int perc = bstats.startAddingCpuLocked();
2240                            int totalUTime = 0;
2241                            int totalSTime = 0;
2242                            final int N = mProcessCpuTracker.countStats();
2243                            for (int i=0; i<N; i++) {
2244                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2245                                if (!st.working) {
2246                                    continue;
2247                                }
2248                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2249                                int otherUTime = (st.rel_utime*perc)/100;
2250                                int otherSTime = (st.rel_stime*perc)/100;
2251                                totalUTime += otherUTime;
2252                                totalSTime += otherSTime;
2253                                if (pr != null) {
2254                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2255                                    if (ps == null || !ps.isActive()) {
2256                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2257                                                pr.info.uid, pr.processName);
2258                                    }
2259                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2260                                            st.rel_stime-otherSTime);
2261                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2262                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2263                                } else {
2264                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2265                                    if (ps == null || !ps.isActive()) {
2266                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2267                                                bstats.mapUid(st.uid), st.name);
2268                                    }
2269                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2270                                            st.rel_stime-otherSTime);
2271                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2272                                }
2273                            }
2274                            bstats.finishAddingCpuLocked(perc, totalUTime,
2275                                    totalSTime, cpuSpeedTimes);
2276                        }
2277                    }
2278                }
2279
2280                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2281                    mLastWriteTime = now;
2282                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2283                }
2284            }
2285        }
2286    }
2287
2288    @Override
2289    public void batteryNeedsCpuUpdate() {
2290        updateCpuStatsNow();
2291    }
2292
2293    @Override
2294    public void batteryPowerChanged(boolean onBattery) {
2295        // When plugging in, update the CPU stats first before changing
2296        // the plug state.
2297        updateCpuStatsNow();
2298        synchronized (this) {
2299            synchronized(mPidsSelfLocked) {
2300                mOnBattery = DEBUG_POWER ? true : onBattery;
2301            }
2302        }
2303    }
2304
2305    /**
2306     * Initialize the application bind args. These are passed to each
2307     * process when the bindApplication() IPC is sent to the process. They're
2308     * lazily setup to make sure the services are running when they're asked for.
2309     */
2310    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2311        if (mAppBindArgs == null) {
2312            mAppBindArgs = new HashMap<>();
2313
2314            // Isolated processes won't get this optimization, so that we don't
2315            // violate the rules about which services they have access to.
2316            if (!isolated) {
2317                // Setup the application init args
2318                mAppBindArgs.put("package", ServiceManager.getService("package"));
2319                mAppBindArgs.put("window", ServiceManager.getService("window"));
2320                mAppBindArgs.put(Context.ALARM_SERVICE,
2321                        ServiceManager.getService(Context.ALARM_SERVICE));
2322            }
2323        }
2324        return mAppBindArgs;
2325    }
2326
2327    final void setFocusedActivityLocked(ActivityRecord r) {
2328        if (mFocusedActivity != r) {
2329            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2330            mFocusedActivity = r;
2331            if (r.task != null && r.task.voiceInteractor != null) {
2332                startRunningVoiceLocked();
2333            } else {
2334                finishRunningVoiceLocked();
2335            }
2336            mStackSupervisor.setFocusedStack(r);
2337            if (r != null) {
2338                mWindowManager.setFocusedApp(r.appToken, true);
2339            }
2340            applyUpdateLockStateLocked(r);
2341        }
2342    }
2343
2344    final void clearFocusedActivity(ActivityRecord r) {
2345        if (mFocusedActivity == r) {
2346            mFocusedActivity = null;
2347        }
2348    }
2349
2350    @Override
2351    public void setFocusedStack(int stackId) {
2352        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2353        synchronized (ActivityManagerService.this) {
2354            ActivityStack stack = mStackSupervisor.getStack(stackId);
2355            if (stack != null) {
2356                ActivityRecord r = stack.topRunningActivityLocked(null);
2357                if (r != null) {
2358                    setFocusedActivityLocked(r);
2359                }
2360            }
2361        }
2362    }
2363
2364    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2365    @Override
2366    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2367        synchronized (ActivityManagerService.this) {
2368            if (listener != null) {
2369                mTaskStackListeners.register(listener);
2370            }
2371        }
2372    }
2373
2374    @Override
2375    public void notifyActivityDrawn(IBinder token) {
2376        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2377        synchronized (this) {
2378            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2379            if (r != null) {
2380                r.task.stack.notifyActivityDrawnLocked(r);
2381            }
2382        }
2383    }
2384
2385    final void applyUpdateLockStateLocked(ActivityRecord r) {
2386        // Modifications to the UpdateLock state are done on our handler, outside
2387        // the activity manager's locks.  The new state is determined based on the
2388        // state *now* of the relevant activity record.  The object is passed to
2389        // the handler solely for logging detail, not to be consulted/modified.
2390        final boolean nextState = r != null && r.immersive;
2391        mHandler.sendMessage(
2392                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2393    }
2394
2395    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2396        Message msg = Message.obtain();
2397        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2398        msg.obj = r.task.askedCompatMode ? null : r;
2399        mHandler.sendMessage(msg);
2400    }
2401
2402    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2403            String what, Object obj, ProcessRecord srcApp) {
2404        app.lastActivityTime = now;
2405
2406        if (app.activities.size() > 0) {
2407            // Don't want to touch dependent processes that are hosting activities.
2408            return index;
2409        }
2410
2411        int lrui = mLruProcesses.lastIndexOf(app);
2412        if (lrui < 0) {
2413            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2414                    + what + " " + obj + " from " + srcApp);
2415            return index;
2416        }
2417
2418        if (lrui >= index) {
2419            // Don't want to cause this to move dependent processes *back* in the
2420            // list as if they were less frequently used.
2421            return index;
2422        }
2423
2424        if (lrui >= mLruProcessActivityStart) {
2425            // Don't want to touch dependent processes that are hosting activities.
2426            return index;
2427        }
2428
2429        mLruProcesses.remove(lrui);
2430        if (index > 0) {
2431            index--;
2432        }
2433        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2434                + " in LRU list: " + app);
2435        mLruProcesses.add(index, app);
2436        return index;
2437    }
2438
2439    final void removeLruProcessLocked(ProcessRecord app) {
2440        int lrui = mLruProcesses.lastIndexOf(app);
2441        if (lrui >= 0) {
2442            if (!app.killed) {
2443                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2444                Process.killProcessQuiet(app.pid);
2445                Process.killProcessGroup(app.info.uid, app.pid);
2446            }
2447            if (lrui <= mLruProcessActivityStart) {
2448                mLruProcessActivityStart--;
2449            }
2450            if (lrui <= mLruProcessServiceStart) {
2451                mLruProcessServiceStart--;
2452            }
2453            mLruProcesses.remove(lrui);
2454        }
2455    }
2456
2457    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2458            ProcessRecord client) {
2459        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2460                || app.treatLikeActivity;
2461        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2462        if (!activityChange && hasActivity) {
2463            // The process has activities, so we are only allowing activity-based adjustments
2464            // to move it.  It should be kept in the front of the list with other
2465            // processes that have activities, and we don't want those to change their
2466            // order except due to activity operations.
2467            return;
2468        }
2469
2470        mLruSeq++;
2471        final long now = SystemClock.uptimeMillis();
2472        app.lastActivityTime = now;
2473
2474        // First a quick reject: if the app is already at the position we will
2475        // put it, then there is nothing to do.
2476        if (hasActivity) {
2477            final int N = mLruProcesses.size();
2478            if (N > 0 && mLruProcesses.get(N-1) == app) {
2479                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2480                return;
2481            }
2482        } else {
2483            if (mLruProcessServiceStart > 0
2484                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2485                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2486                return;
2487            }
2488        }
2489
2490        int lrui = mLruProcesses.lastIndexOf(app);
2491
2492        if (app.persistent && lrui >= 0) {
2493            // We don't care about the position of persistent processes, as long as
2494            // they are in the list.
2495            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2496            return;
2497        }
2498
2499        /* In progress: compute new position first, so we can avoid doing work
2500           if the process is not actually going to move.  Not yet working.
2501        int addIndex;
2502        int nextIndex;
2503        boolean inActivity = false, inService = false;
2504        if (hasActivity) {
2505            // Process has activities, put it at the very tipsy-top.
2506            addIndex = mLruProcesses.size();
2507            nextIndex = mLruProcessServiceStart;
2508            inActivity = true;
2509        } else if (hasService) {
2510            // Process has services, put it at the top of the service list.
2511            addIndex = mLruProcessActivityStart;
2512            nextIndex = mLruProcessServiceStart;
2513            inActivity = true;
2514            inService = true;
2515        } else  {
2516            // Process not otherwise of interest, it goes to the top of the non-service area.
2517            addIndex = mLruProcessServiceStart;
2518            if (client != null) {
2519                int clientIndex = mLruProcesses.lastIndexOf(client);
2520                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2521                        + app);
2522                if (clientIndex >= 0 && addIndex > clientIndex) {
2523                    addIndex = clientIndex;
2524                }
2525            }
2526            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2527        }
2528
2529        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2530                + mLruProcessActivityStart + "): " + app);
2531        */
2532
2533        if (lrui >= 0) {
2534            if (lrui < mLruProcessActivityStart) {
2535                mLruProcessActivityStart--;
2536            }
2537            if (lrui < mLruProcessServiceStart) {
2538                mLruProcessServiceStart--;
2539            }
2540            /*
2541            if (addIndex > lrui) {
2542                addIndex--;
2543            }
2544            if (nextIndex > lrui) {
2545                nextIndex--;
2546            }
2547            */
2548            mLruProcesses.remove(lrui);
2549        }
2550
2551        /*
2552        mLruProcesses.add(addIndex, app);
2553        if (inActivity) {
2554            mLruProcessActivityStart++;
2555        }
2556        if (inService) {
2557            mLruProcessActivityStart++;
2558        }
2559        */
2560
2561        int nextIndex;
2562        if (hasActivity) {
2563            final int N = mLruProcesses.size();
2564            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2565                // Process doesn't have activities, but has clients with
2566                // activities...  move it up, but one below the top (the top
2567                // should always have a real activity).
2568                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2569                mLruProcesses.add(N-1, app);
2570                // To keep it from spamming the LRU list (by making a bunch of clients),
2571                // we will push down any other entries owned by the app.
2572                final int uid = app.info.uid;
2573                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2574                    ProcessRecord subProc = mLruProcesses.get(i);
2575                    if (subProc.info.uid == uid) {
2576                        // We want to push this one down the list.  If the process after
2577                        // it is for the same uid, however, don't do so, because we don't
2578                        // want them internally to be re-ordered.
2579                        if (mLruProcesses.get(i-1).info.uid != uid) {
2580                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2581                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2582                            ProcessRecord tmp = mLruProcesses.get(i);
2583                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2584                            mLruProcesses.set(i-1, tmp);
2585                            i--;
2586                        }
2587                    } else {
2588                        // A gap, we can stop here.
2589                        break;
2590                    }
2591                }
2592            } else {
2593                // Process has activities, put it at the very tipsy-top.
2594                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2595                mLruProcesses.add(app);
2596            }
2597            nextIndex = mLruProcessServiceStart;
2598        } else if (hasService) {
2599            // Process has services, put it at the top of the service list.
2600            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2601            mLruProcesses.add(mLruProcessActivityStart, app);
2602            nextIndex = mLruProcessServiceStart;
2603            mLruProcessActivityStart++;
2604        } else  {
2605            // Process not otherwise of interest, it goes to the top of the non-service area.
2606            int index = mLruProcessServiceStart;
2607            if (client != null) {
2608                // If there is a client, don't allow the process to be moved up higher
2609                // in the list than that client.
2610                int clientIndex = mLruProcesses.lastIndexOf(client);
2611                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2612                        + " when updating " + app);
2613                if (clientIndex <= lrui) {
2614                    // Don't allow the client index restriction to push it down farther in the
2615                    // list than it already is.
2616                    clientIndex = lrui;
2617                }
2618                if (clientIndex >= 0 && index > clientIndex) {
2619                    index = clientIndex;
2620                }
2621            }
2622            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2623            mLruProcesses.add(index, app);
2624            nextIndex = index-1;
2625            mLruProcessActivityStart++;
2626            mLruProcessServiceStart++;
2627        }
2628
2629        // If the app is currently using a content provider or service,
2630        // bump those processes as well.
2631        for (int j=app.connections.size()-1; j>=0; j--) {
2632            ConnectionRecord cr = app.connections.valueAt(j);
2633            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2634                    && cr.binding.service.app != null
2635                    && cr.binding.service.app.lruSeq != mLruSeq
2636                    && !cr.binding.service.app.persistent) {
2637                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2638                        "service connection", cr, app);
2639            }
2640        }
2641        for (int j=app.conProviders.size()-1; j>=0; j--) {
2642            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2643            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2644                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2645                        "provider reference", cpr, app);
2646            }
2647        }
2648    }
2649
2650    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2651        if (uid == Process.SYSTEM_UID) {
2652            // The system gets to run in any process.  If there are multiple
2653            // processes with the same uid, just pick the first (this
2654            // should never happen).
2655            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2656            if (procs == null) return null;
2657            final int N = procs.size();
2658            for (int i = 0; i < N; i++) {
2659                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2660            }
2661        }
2662        ProcessRecord proc = mProcessNames.get(processName, uid);
2663        if (false && proc != null && !keepIfLarge
2664                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2665                && proc.lastCachedPss >= 4000) {
2666            // Turn this condition on to cause killing to happen regularly, for testing.
2667            if (proc.baseProcessTracker != null) {
2668                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2669            }
2670            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2671        } else if (proc != null && !keepIfLarge
2672                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2673                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2674            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2675            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2676                if (proc.baseProcessTracker != null) {
2677                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2678                }
2679                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2680            }
2681        }
2682        return proc;
2683    }
2684
2685    void ensurePackageDexOpt(String packageName) {
2686        IPackageManager pm = AppGlobals.getPackageManager();
2687        try {
2688            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2689                mDidDexOpt = true;
2690            }
2691        } catch (RemoteException e) {
2692        }
2693    }
2694
2695    boolean isNextTransitionForward() {
2696        int transit = mWindowManager.getPendingAppTransition();
2697        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2698                || transit == AppTransition.TRANSIT_TASK_OPEN
2699                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2700    }
2701
2702    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2703            String processName, String abiOverride, int uid, Runnable crashHandler) {
2704        synchronized(this) {
2705            ApplicationInfo info = new ApplicationInfo();
2706            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2707            // For isolated processes, the former contains the parent's uid and the latter the
2708            // actual uid of the isolated process.
2709            // In the special case introduced by this method (which is, starting an isolated
2710            // process directly from the SystemServer without an actual parent app process) the
2711            // closest thing to a parent's uid is SYSTEM_UID.
2712            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2713            // the |isolated| logic in the ProcessRecord constructor.
2714            info.uid = Process.SYSTEM_UID;
2715            info.processName = processName;
2716            info.className = entryPoint;
2717            info.packageName = "android";
2718            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2719                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2720                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2721                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2722                    crashHandler);
2723            return proc != null ? proc.pid : 0;
2724        }
2725    }
2726
2727    final ProcessRecord startProcessLocked(String processName,
2728            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2729            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2730            boolean isolated, boolean keepIfLarge) {
2731        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2732                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2733                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2734                null /* crashHandler */);
2735    }
2736
2737    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2738            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2739            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2740            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2741        long startTime = SystemClock.elapsedRealtime();
2742        ProcessRecord app;
2743        if (!isolated) {
2744            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2745            checkTime(startTime, "startProcess: after getProcessRecord");
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2767                checkTime(startTime, "startProcess: done, added package to proc");
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            checkTime(startTime, "startProcess: bad proc running, killing");
2775            Process.killProcessGroup(app.info.uid, app.pid);
2776            handleAppDiedLocked(app, true, true);
2777            checkTime(startTime, "startProcess: done killing old proc");
2778        }
2779
2780        String hostingNameStr = hostingName != null
2781                ? hostingName.flattenToShortString() : null;
2782
2783        if (!isolated) {
2784            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2785                // If we are in the background, then check to see if this process
2786                // is bad.  If so, we will just silently fail.
2787                if (mBadProcesses.get(info.processName, info.uid) != null) {
2788                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2789                            + "/" + info.processName);
2790                    return null;
2791                }
2792            } else {
2793                // When the user is explicitly starting a process, then clear its
2794                // crash count so that we won't make it bad until they see at
2795                // least one crash dialog again, and make the process good again
2796                // if it had been bad.
2797                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2798                        + "/" + info.processName);
2799                mProcessCrashTimes.remove(info.processName, info.uid);
2800                if (mBadProcesses.get(info.processName, info.uid) != null) {
2801                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2802                            UserHandle.getUserId(info.uid), info.uid,
2803                            info.processName);
2804                    mBadProcesses.remove(info.processName, info.uid);
2805                    if (app != null) {
2806                        app.bad = false;
2807                    }
2808                }
2809            }
2810        }
2811
2812        if (app == null) {
2813            checkTime(startTime, "startProcess: creating new process record");
2814            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2815            if (app == null) {
2816                Slog.w(TAG, "Failed making new process record for "
2817                        + processName + "/" + info.uid + " isolated=" + isolated);
2818                return null;
2819            }
2820            app.crashHandler = crashHandler;
2821            mProcessNames.put(processName, app.uid, app);
2822            if (isolated) {
2823                mIsolatedProcesses.put(app.uid, app);
2824            }
2825            checkTime(startTime, "startProcess: done creating new process record");
2826        } else {
2827            // If this is a new package in the process, add the package to the list
2828            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2829            checkTime(startTime, "startProcess: added package to existing proc");
2830        }
2831
2832        // If the system is not ready yet, then hold off on starting this
2833        // process until it is.
2834        if (!mProcessesReady
2835                && !isAllowedWhileBooting(info)
2836                && !allowWhileBooting) {
2837            if (!mProcessesOnHold.contains(app)) {
2838                mProcessesOnHold.add(app);
2839            }
2840            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2841            checkTime(startTime, "startProcess: returning with proc on hold");
2842            return app;
2843        }
2844
2845        checkTime(startTime, "startProcess: stepping in to startProcess");
2846        startProcessLocked(
2847                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2848        checkTime(startTime, "startProcess: done starting proc!");
2849        return (app.pid != 0) ? app : null;
2850    }
2851
2852    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2853        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2854    }
2855
2856    private final void startProcessLocked(ProcessRecord app,
2857            String hostingType, String hostingNameStr) {
2858        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2859                null /* entryPoint */, null /* entryPointArgs */);
2860    }
2861
2862    private final void startProcessLocked(ProcessRecord app, String hostingType,
2863            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2864        long startTime = SystemClock.elapsedRealtime();
2865        if (app.pid > 0 && app.pid != MY_PID) {
2866            checkTime(startTime, "startProcess: removing from pids map");
2867            synchronized (mPidsSelfLocked) {
2868                mPidsSelfLocked.remove(app.pid);
2869                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2870            }
2871            checkTime(startTime, "startProcess: done removing from pids map");
2872            app.setPid(0);
2873        }
2874
2875        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2876                "startProcessLocked removing on hold: " + app);
2877        mProcessesOnHold.remove(app);
2878
2879        checkTime(startTime, "startProcess: starting to update cpu stats");
2880        updateCpuStats();
2881        checkTime(startTime, "startProcess: done updating cpu stats");
2882
2883        try {
2884            int uid = app.uid;
2885
2886            int[] gids = null;
2887            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2888            if (!app.isolated) {
2889                int[] permGids = null;
2890                try {
2891                    checkTime(startTime, "startProcess: getting gids from package manager");
2892                    final PackageManager pm = mContext.getPackageManager();
2893                    permGids = pm.getPackageGids(app.info.packageName);
2894
2895                    if (Environment.isExternalStorageEmulated()) {
2896                        checkTime(startTime, "startProcess: checking external storage perm");
2897                        if (pm.checkPermission(
2898                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2899                                app.info.packageName) == PERMISSION_GRANTED) {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2901                        } else {
2902                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2903                        }
2904                    }
2905                } catch (PackageManager.NameNotFoundException e) {
2906                    Slog.w(TAG, "Unable to retrieve gids", e);
2907                }
2908
2909                /*
2910                 * Add shared application and profile GIDs so applications can share some
2911                 * resources like shared libraries and access user-wide resources
2912                 */
2913                if (permGids == null) {
2914                    gids = new int[2];
2915                } else {
2916                    gids = new int[permGids.length + 2];
2917                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2918                }
2919                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2920                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2921            }
2922            checkTime(startTime, "startProcess: building args");
2923            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2924                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2925                        && mTopComponent != null
2926                        && app.processName.equals(mTopComponent.getPackageName())) {
2927                    uid = 0;
2928                }
2929                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2930                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2931                    uid = 0;
2932                }
2933            }
2934            int debugFlags = 0;
2935            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2936                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2937                // Also turn on CheckJNI for debuggable apps. It's quite
2938                // awkward to turn on otherwise.
2939                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2940            }
2941            // Run the app in safe mode if its manifest requests so or the
2942            // system is booted in safe mode.
2943            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2944                mSafeMode == true) {
2945                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2946            }
2947            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2948                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2949            }
2950            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2951                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2952            }
2953            if ("1".equals(SystemProperties.get("debug.assert"))) {
2954                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2955            }
2956
2957            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2958            if (requiredAbi == null) {
2959                requiredAbi = Build.SUPPORTED_ABIS[0];
2960            }
2961
2962            String instructionSet = null;
2963            if (app.info.primaryCpuAbi != null) {
2964                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2965            }
2966
2967            // Start the process.  It will either succeed and return a result containing
2968            // the PID of the new process, or else throw a RuntimeException.
2969            boolean isActivityProcess = (entryPoint == null);
2970            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2971            checkTime(startTime, "startProcess: asking zygote to start proc");
2972            Process.ProcessStartResult startResult = Process.start(entryPoint,
2973                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2974                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2975                    app.info.dataDir, entryPointArgs);
2976            checkTime(startTime, "startProcess: returned from zygote!");
2977
2978            if (app.isolated) {
2979                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2980            }
2981            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2982            checkTime(startTime, "startProcess: done updating battery stats");
2983
2984            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2985                    UserHandle.getUserId(uid), startResult.pid, uid,
2986                    app.processName, hostingType,
2987                    hostingNameStr != null ? hostingNameStr : "");
2988
2989            if (app.persistent) {
2990                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2991            }
2992
2993            checkTime(startTime, "startProcess: building log message");
2994            StringBuilder buf = mStringBuilder;
2995            buf.setLength(0);
2996            buf.append("Start proc ");
2997            buf.append(app.processName);
2998            if (!isActivityProcess) {
2999                buf.append(" [");
3000                buf.append(entryPoint);
3001                buf.append("]");
3002            }
3003            buf.append(" for ");
3004            buf.append(hostingType);
3005            if (hostingNameStr != null) {
3006                buf.append(" ");
3007                buf.append(hostingNameStr);
3008            }
3009            buf.append(": pid=");
3010            buf.append(startResult.pid);
3011            buf.append(" uid=");
3012            buf.append(uid);
3013            buf.append(" gids={");
3014            if (gids != null) {
3015                for (int gi=0; gi<gids.length; gi++) {
3016                    if (gi != 0) buf.append(", ");
3017                    buf.append(gids[gi]);
3018
3019                }
3020            }
3021            buf.append("}");
3022            if (requiredAbi != null) {
3023                buf.append(" abi=");
3024                buf.append(requiredAbi);
3025            }
3026            Slog.i(TAG, buf.toString());
3027            app.setPid(startResult.pid);
3028            app.usingWrapper = startResult.usingWrapper;
3029            app.removed = false;
3030            app.killed = false;
3031            app.killedByAm = false;
3032            checkTime(startTime, "startProcess: starting to update pids map");
3033            synchronized (mPidsSelfLocked) {
3034                this.mPidsSelfLocked.put(startResult.pid, app);
3035                if (isActivityProcess) {
3036                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3037                    msg.obj = app;
3038                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3039                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3040                }
3041            }
3042            checkTime(startTime, "startProcess: done updating pids map");
3043        } catch (RuntimeException e) {
3044            // XXX do better error recovery.
3045            app.setPid(0);
3046            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3047            if (app.isolated) {
3048                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3049            }
3050            Slog.e(TAG, "Failure starting process " + app.processName, e);
3051        }
3052    }
3053
3054    void updateUsageStats(ActivityRecord component, boolean resumed) {
3055        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3056        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3057        if (resumed) {
3058            if (mUsageStatsService != null) {
3059                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3060                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3061            }
3062            synchronized (stats) {
3063                stats.noteActivityResumedLocked(component.app.uid);
3064            }
3065        } else {
3066            if (mUsageStatsService != null) {
3067                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3068                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3069            }
3070            synchronized (stats) {
3071                stats.noteActivityPausedLocked(component.app.uid);
3072            }
3073        }
3074    }
3075
3076    Intent getHomeIntent() {
3077        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3078        intent.setComponent(mTopComponent);
3079        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3080            intent.addCategory(Intent.CATEGORY_HOME);
3081        }
3082        return intent;
3083    }
3084
3085    boolean startHomeActivityLocked(int userId) {
3086        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3087                && mTopAction == null) {
3088            // We are running in factory test mode, but unable to find
3089            // the factory test app, so just sit around displaying the
3090            // error message and don't try to start anything.
3091            return false;
3092        }
3093        Intent intent = getHomeIntent();
3094        ActivityInfo aInfo =
3095            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3096        if (aInfo != null) {
3097            intent.setComponent(new ComponentName(
3098                    aInfo.applicationInfo.packageName, aInfo.name));
3099            // Don't do this if the home app is currently being
3100            // instrumented.
3101            aInfo = new ActivityInfo(aInfo);
3102            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3103            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3104                    aInfo.applicationInfo.uid, true);
3105            if (app == null || app.instrumentationClass == null) {
3106                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3107                mStackSupervisor.startHomeActivity(intent, aInfo);
3108            }
3109        }
3110
3111        return true;
3112    }
3113
3114    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3115        ActivityInfo ai = null;
3116        ComponentName comp = intent.getComponent();
3117        try {
3118            if (comp != null) {
3119                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3120            } else {
3121                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3122                        intent,
3123                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3124                            flags, userId);
3125
3126                if (info != null) {
3127                    ai = info.activityInfo;
3128                }
3129            }
3130        } catch (RemoteException e) {
3131            // ignore
3132        }
3133
3134        return ai;
3135    }
3136
3137    /**
3138     * Starts the "new version setup screen" if appropriate.
3139     */
3140    void startSetupActivityLocked() {
3141        // Only do this once per boot.
3142        if (mCheckedForSetup) {
3143            return;
3144        }
3145
3146        // We will show this screen if the current one is a different
3147        // version than the last one shown, and we are not running in
3148        // low-level factory test mode.
3149        final ContentResolver resolver = mContext.getContentResolver();
3150        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3151                Settings.Global.getInt(resolver,
3152                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3153            mCheckedForSetup = true;
3154
3155            // See if we should be showing the platform update setup UI.
3156            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3157            List<ResolveInfo> ris = mContext.getPackageManager()
3158                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3159
3160            // We don't allow third party apps to replace this.
3161            ResolveInfo ri = null;
3162            for (int i=0; ris != null && i<ris.size(); i++) {
3163                if ((ris.get(i).activityInfo.applicationInfo.flags
3164                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3165                    ri = ris.get(i);
3166                    break;
3167                }
3168            }
3169
3170            if (ri != null) {
3171                String vers = ri.activityInfo.metaData != null
3172                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3173                        : null;
3174                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3175                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3176                            Intent.METADATA_SETUP_VERSION);
3177                }
3178                String lastVers = Settings.Secure.getString(
3179                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3180                if (vers != null && !vers.equals(lastVers)) {
3181                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3182                    intent.setComponent(new ComponentName(
3183                            ri.activityInfo.packageName, ri.activityInfo.name));
3184                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3185                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3186                            null);
3187                }
3188            }
3189        }
3190    }
3191
3192    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3193        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3194    }
3195
3196    void enforceNotIsolatedCaller(String caller) {
3197        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3198            throw new SecurityException("Isolated process not allowed to call " + caller);
3199        }
3200    }
3201
3202    void enforceShellRestriction(String restriction, int userHandle) {
3203        if (Binder.getCallingUid() == Process.SHELL_UID) {
3204            if (userHandle < 0
3205                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3206                throw new SecurityException("Shell does not have permission to access user "
3207                        + userHandle);
3208            }
3209        }
3210    }
3211
3212    @Override
3213    public int getFrontActivityScreenCompatMode() {
3214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3215        synchronized (this) {
3216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3217        }
3218    }
3219
3220    @Override
3221    public void setFrontActivityScreenCompatMode(int mode) {
3222        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3223                "setFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3226        }
3227    }
3228
3229    @Override
3230    public int getPackageScreenCompatMode(String packageName) {
3231        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3232        synchronized (this) {
3233            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3234        }
3235    }
3236
3237    @Override
3238    public void setPackageScreenCompatMode(String packageName, int mode) {
3239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3240                "setPackageScreenCompatMode");
3241        synchronized (this) {
3242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3243        }
3244    }
3245
3246    @Override
3247    public boolean getPackageAskScreenCompat(String packageName) {
3248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3249        synchronized (this) {
3250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3251        }
3252    }
3253
3254    @Override
3255    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setPackageAskScreenCompat");
3258        synchronized (this) {
3259            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3260        }
3261    }
3262
3263    private void dispatchProcessesChanged() {
3264        int N;
3265        synchronized (this) {
3266            N = mPendingProcessChanges.size();
3267            if (mActiveProcessChanges.length < N) {
3268                mActiveProcessChanges = new ProcessChangeItem[N];
3269            }
3270            mPendingProcessChanges.toArray(mActiveProcessChanges);
3271            mAvailProcessChanges.addAll(mPendingProcessChanges);
3272            mPendingProcessChanges.clear();
3273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3274        }
3275
3276        int i = mProcessObservers.beginBroadcast();
3277        while (i > 0) {
3278            i--;
3279            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3280            if (observer != null) {
3281                try {
3282                    for (int j=0; j<N; j++) {
3283                        ProcessChangeItem item = mActiveProcessChanges[j];
3284                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3285                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3286                                    + item.pid + " uid=" + item.uid + ": "
3287                                    + item.foregroundActivities);
3288                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3289                                    item.foregroundActivities);
3290                        }
3291                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3292                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3293                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3294                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3295                        }
3296                    }
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    private void dispatchProcessDied(int pid, int uid) {
3305        int i = mProcessObservers.beginBroadcast();
3306        while (i > 0) {
3307            i--;
3308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3309            if (observer != null) {
3310                try {
3311                    observer.onProcessDied(pid, uid);
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    @Override
3320    public final int startActivity(IApplicationThread caller, String callingPackage,
3321            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3322            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3323        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3324            resultWho, requestCode, startFlags, profilerInfo, options,
3325            UserHandle.getCallingUserId());
3326    }
3327
3328    @Override
3329    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3331            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3332        enforceNotIsolatedCaller("startActivity");
3333        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3334                false, ALLOW_FULL_ONLY, "startActivity", null);
3335        // TODO: Switch to user app stacks here.
3336        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3337                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3338                profilerInfo, null, null, options, userId, null, null);
3339    }
3340
3341    @Override
3342    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3344            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3345
3346        // This is very dangerous -- it allows you to perform a start activity (including
3347        // permission grants) as any app that may launch one of your own activities.  So
3348        // we will only allow this to be done from activities that are part of the core framework,
3349        // and then only when they are running as the system.
3350        final ActivityRecord sourceRecord;
3351        final int targetUid;
3352        final String targetPackage;
3353        synchronized (this) {
3354            if (resultTo == null) {
3355                throw new SecurityException("Must be called from an activity");
3356            }
3357            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3358            if (sourceRecord == null) {
3359                throw new SecurityException("Called with bad activity token: " + resultTo);
3360            }
3361            if (!sourceRecord.info.packageName.equals("android")) {
3362                throw new SecurityException(
3363                        "Must be called from an activity that is declared in the android package");
3364            }
3365            if (sourceRecord.app == null) {
3366                throw new SecurityException("Called without a process attached to activity");
3367            }
3368            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3369                // This is still okay, as long as this activity is running under the
3370                // uid of the original calling activity.
3371                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3372                    throw new SecurityException(
3373                            "Calling activity in uid " + sourceRecord.app.uid
3374                                    + " must be system uid or original calling uid "
3375                                    + sourceRecord.launchedFromUid);
3376                }
3377            }
3378            targetUid = sourceRecord.launchedFromUid;
3379            targetPackage = sourceRecord.launchedFromPackage;
3380        }
3381
3382        if (userId == UserHandle.USER_NULL) {
3383            userId = UserHandle.getUserId(sourceRecord.app.uid);
3384        }
3385
3386        // TODO: Switch to user app stacks here.
3387        try {
3388            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3389                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3390                    null, null, options, userId, null, null);
3391            return ret;
3392        } catch (SecurityException e) {
3393            // XXX need to figure out how to propagate to original app.
3394            // A SecurityException here is generally actually a fault of the original
3395            // calling activity (such as a fairly granting permissions), so propagate it
3396            // back to them.
3397            /*
3398            StringBuilder msg = new StringBuilder();
3399            msg.append("While launching");
3400            msg.append(intent.toString());
3401            msg.append(": ");
3402            msg.append(e.getMessage());
3403            */
3404            throw e;
3405        }
3406    }
3407
3408    @Override
3409    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3410            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3411            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3412        enforceNotIsolatedCaller("startActivityAndWait");
3413        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3414                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3415        WaitResult res = new WaitResult();
3416        // TODO: Switch to user app stacks here.
3417        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3418                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3419                options, userId, null, null);
3420        return res;
3421    }
3422
3423    @Override
3424    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3425            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3426            int startFlags, Configuration config, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivityWithConfig");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3430        // TODO: Switch to user app stacks here.
3431        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3432                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3433                null, null, config, options, userId, null, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startActivityIntentSender(IApplicationThread caller,
3439            IntentSender intent, Intent fillInIntent, String resolvedType,
3440            IBinder resultTo, String resultWho, int requestCode,
3441            int flagsMask, int flagsValues, Bundle options) {
3442        enforceNotIsolatedCaller("startActivityIntentSender");
3443        // Refuse possible leaked file descriptors
3444        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        IIntentSender sender = intent.getTarget();
3449        if (!(sender instanceof PendingIntentRecord)) {
3450            throw new IllegalArgumentException("Bad PendingIntent object");
3451        }
3452
3453        PendingIntentRecord pir = (PendingIntentRecord)sender;
3454
3455        synchronized (this) {
3456            // If this is coming from the currently resumed activity, it is
3457            // effectively saying that app switches are allowed at this point.
3458            final ActivityStack stack = getFocusedStack();
3459            if (stack.mResumedActivity != null &&
3460                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3461                mAppSwitchesAllowedTime = 0;
3462            }
3463        }
3464        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3465                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3466        return ret;
3467    }
3468
3469    @Override
3470    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3471            Intent intent, String resolvedType, IVoiceInteractionSession session,
3472            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3473            Bundle options, int userId) {
3474        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3475                != PackageManager.PERMISSION_GRANTED) {
3476            String msg = "Permission Denial: startVoiceActivity() from pid="
3477                    + Binder.getCallingPid()
3478                    + ", uid=" + Binder.getCallingUid()
3479                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3480            Slog.w(TAG, msg);
3481            throw new SecurityException(msg);
3482        }
3483        if (session == null || interactor == null) {
3484            throw new NullPointerException("null session or interactor");
3485        }
3486        userId = handleIncomingUser(callingPid, callingUid, userId,
3487                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3488        // TODO: Switch to user app stacks here.
3489        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3490                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3491                null, options, userId, null, null);
3492    }
3493
3494    @Override
3495    public boolean startNextMatchingActivity(IBinder callingActivity,
3496            Intent intent, Bundle options) {
3497        // Refuse possible leaked file descriptors
3498        if (intent != null && intent.hasFileDescriptors() == true) {
3499            throw new IllegalArgumentException("File descriptors passed in Intent");
3500        }
3501
3502        synchronized (this) {
3503            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3504            if (r == null) {
3505                ActivityOptions.abort(options);
3506                return false;
3507            }
3508            if (r.app == null || r.app.thread == null) {
3509                // The caller is not running...  d'oh!
3510                ActivityOptions.abort(options);
3511                return false;
3512            }
3513            intent = new Intent(intent);
3514            // The caller is not allowed to change the data.
3515            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3516            // And we are resetting to find the next component...
3517            intent.setComponent(null);
3518
3519            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3520
3521            ActivityInfo aInfo = null;
3522            try {
3523                List<ResolveInfo> resolves =
3524                    AppGlobals.getPackageManager().queryIntentActivities(
3525                            intent, r.resolvedType,
3526                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3527                            UserHandle.getCallingUserId());
3528
3529                // Look for the original activity in the list...
3530                final int N = resolves != null ? resolves.size() : 0;
3531                for (int i=0; i<N; i++) {
3532                    ResolveInfo rInfo = resolves.get(i);
3533                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3534                            && rInfo.activityInfo.name.equals(r.info.name)) {
3535                        // We found the current one...  the next matching is
3536                        // after it.
3537                        i++;
3538                        if (i<N) {
3539                            aInfo = resolves.get(i).activityInfo;
3540                        }
3541                        if (debug) {
3542                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3543                                    + "/" + r.info.name);
3544                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3545                                    + "/" + aInfo.name);
3546                        }
3547                        break;
3548                    }
3549                }
3550            } catch (RemoteException e) {
3551            }
3552
3553            if (aInfo == null) {
3554                // Nobody who is next!
3555                ActivityOptions.abort(options);
3556                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3557                return false;
3558            }
3559
3560            intent.setComponent(new ComponentName(
3561                    aInfo.applicationInfo.packageName, aInfo.name));
3562            intent.setFlags(intent.getFlags()&~(
3563                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3564                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3565                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3566                    Intent.FLAG_ACTIVITY_NEW_TASK));
3567
3568            // Okay now we need to start the new activity, replacing the
3569            // currently running activity.  This is a little tricky because
3570            // we want to start the new one as if the current one is finished,
3571            // but not finish the current one first so that there is no flicker.
3572            // And thus...
3573            final boolean wasFinishing = r.finishing;
3574            r.finishing = true;
3575
3576            // Propagate reply information over to the new activity.
3577            final ActivityRecord resultTo = r.resultTo;
3578            final String resultWho = r.resultWho;
3579            final int requestCode = r.requestCode;
3580            r.resultTo = null;
3581            if (resultTo != null) {
3582                resultTo.removeResultsLocked(r, resultWho, requestCode);
3583            }
3584
3585            final long origId = Binder.clearCallingIdentity();
3586            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3587                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3588                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3589                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3590            Binder.restoreCallingIdentity(origId);
3591
3592            r.finishing = wasFinishing;
3593            if (res != ActivityManager.START_SUCCESS) {
3594                return false;
3595            }
3596            return true;
3597        }
3598    }
3599
3600    @Override
3601    public final int startActivityFromRecents(int taskId, Bundle options) {
3602        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startActivityFromRecents called without " +
3604                    START_TASKS_FROM_RECENTS;
3605            Slog.w(TAG, msg);
3606            throw new SecurityException(msg);
3607        }
3608        return startActivityFromRecentsInner(taskId, options);
3609    }
3610
3611    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3612        final TaskRecord task;
3613        final int callingUid;
3614        final String callingPackage;
3615        final Intent intent;
3616        final int userId;
3617        synchronized (this) {
3618            task = recentTaskForIdLocked(taskId);
3619            if (task == null) {
3620                throw new IllegalArgumentException("Task " + taskId + " not found.");
3621            }
3622            if (task.getRootActivity() != null) {
3623                moveTaskToFrontLocked(task.taskId, 0, null);
3624                return ActivityManager.START_TASK_TO_FRONT;
3625            }
3626            callingUid = task.mCallingUid;
3627            callingPackage = task.mCallingPackage;
3628            intent = task.intent;
3629            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3630            userId = task.userId;
3631        }
3632        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3633                options, userId, null, task);
3634    }
3635
3636    final int startActivityInPackage(int uid, String callingPackage,
3637            Intent intent, String resolvedType, IBinder resultTo,
3638            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3639            IActivityContainer container, TaskRecord inTask) {
3640
3641        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3642                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3643
3644        // TODO: Switch to user app stacks here.
3645        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3646                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3647                null, null, null, options, userId, container, inTask);
3648        return ret;
3649    }
3650
3651    @Override
3652    public final int startActivities(IApplicationThread caller, String callingPackage,
3653            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3654            int userId) {
3655        enforceNotIsolatedCaller("startActivities");
3656        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3657                false, ALLOW_FULL_ONLY, "startActivity", null);
3658        // TODO: Switch to user app stacks here.
3659        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3660                resolvedTypes, resultTo, options, userId);
3661        return ret;
3662    }
3663
3664    final int startActivitiesInPackage(int uid, String callingPackage,
3665            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3666            Bundle options, int userId) {
3667
3668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3669                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3670        // TODO: Switch to user app stacks here.
3671        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3672                resultTo, options, userId);
3673        return ret;
3674    }
3675
3676    //explicitly remove thd old information in mRecentTasks when removing existing user.
3677    private void removeRecentTasksForUserLocked(int userId) {
3678        if(userId <= 0) {
3679            Slog.i(TAG, "Can't remove recent task on user " + userId);
3680            return;
3681        }
3682
3683        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3684            TaskRecord tr = mRecentTasks.get(i);
3685            if (tr.userId == userId) {
3686                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3687                        + " when finishing user" + userId);
3688                mRecentTasks.remove(i);
3689                tr.removedFromRecents();
3690            }
3691        }
3692
3693        // Remove tasks from persistent storage.
3694        notifyTaskPersisterLocked(null, true);
3695    }
3696
3697    // Sort by taskId
3698    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3699        @Override
3700        public int compare(TaskRecord lhs, TaskRecord rhs) {
3701            return rhs.taskId - lhs.taskId;
3702        }
3703    };
3704
3705    // Extract the affiliates of the chain containing mRecentTasks[start].
3706    private int processNextAffiliateChainLocked(int start) {
3707        final TaskRecord startTask = mRecentTasks.get(start);
3708        final int affiliateId = startTask.mAffiliatedTaskId;
3709
3710        // Quick identification of isolated tasks. I.e. those not launched behind.
3711        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3712                startTask.mNextAffiliate == null) {
3713            // There is still a slim chance that there are other tasks that point to this task
3714            // and that the chain is so messed up that this task no longer points to them but
3715            // the gain of this optimization outweighs the risk.
3716            startTask.inRecents = true;
3717            return start + 1;
3718        }
3719
3720        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3721        mTmpRecents.clear();
3722        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3723            final TaskRecord task = mRecentTasks.get(i);
3724            if (task.mAffiliatedTaskId == affiliateId) {
3725                mRecentTasks.remove(i);
3726                mTmpRecents.add(task);
3727            }
3728        }
3729
3730        // Sort them all by taskId. That is the order they were create in and that order will
3731        // always be correct.
3732        Collections.sort(mTmpRecents, mTaskRecordComparator);
3733
3734        // Go through and fix up the linked list.
3735        // The first one is the end of the chain and has no next.
3736        final TaskRecord first = mTmpRecents.get(0);
3737        first.inRecents = true;
3738        if (first.mNextAffiliate != null) {
3739            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3740            first.setNextAffiliate(null);
3741            notifyTaskPersisterLocked(first, false);
3742        }
3743        // Everything in the middle is doubly linked from next to prev.
3744        final int tmpSize = mTmpRecents.size();
3745        for (int i = 0; i < tmpSize - 1; ++i) {
3746            final TaskRecord next = mTmpRecents.get(i);
3747            final TaskRecord prev = mTmpRecents.get(i + 1);
3748            if (next.mPrevAffiliate != prev) {
3749                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3750                        " setting prev=" + prev);
3751                next.setPrevAffiliate(prev);
3752                notifyTaskPersisterLocked(next, false);
3753            }
3754            if (prev.mNextAffiliate != next) {
3755                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3756                        " setting next=" + next);
3757                prev.setNextAffiliate(next);
3758                notifyTaskPersisterLocked(prev, false);
3759            }
3760            prev.inRecents = true;
3761        }
3762        // The last one is the beginning of the list and has no prev.
3763        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3764        if (last.mPrevAffiliate != null) {
3765            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3766            last.setPrevAffiliate(null);
3767            notifyTaskPersisterLocked(last, false);
3768        }
3769
3770        // Insert the group back into mRecentTasks at start.
3771        mRecentTasks.addAll(start, mTmpRecents);
3772
3773        // Let the caller know where we left off.
3774        return start + tmpSize;
3775    }
3776
3777    /**
3778     * Update the recent tasks lists: make sure tasks should still be here (their
3779     * applications / activities still exist), update their availability, fixup ordering
3780     * of affiliations.
3781     */
3782    void cleanupRecentTasksLocked(int userId) {
3783        if (mRecentTasks == null) {
3784            // Happens when called from the packagemanager broadcast before boot.
3785            return;
3786        }
3787
3788        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3789        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3790        final IPackageManager pm = AppGlobals.getPackageManager();
3791        final ActivityInfo dummyAct = new ActivityInfo();
3792        final ApplicationInfo dummyApp = new ApplicationInfo();
3793
3794        int N = mRecentTasks.size();
3795
3796        int[] users = userId == UserHandle.USER_ALL
3797                ? getUsersLocked() : new int[] { userId };
3798        for (int user : users) {
3799            for (int i = 0; i < N; i++) {
3800                TaskRecord task = mRecentTasks.get(i);
3801                if (task.userId != user) {
3802                    // Only look at tasks for the user ID of interest.
3803                    continue;
3804                }
3805                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3806                    // This situation is broken, and we should just get rid of it now.
3807                    mRecentTasks.remove(i);
3808                    task.removedFromRecents();
3809                    i--;
3810                    N--;
3811                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3812                    continue;
3813                }
3814                // Check whether this activity is currently available.
3815                if (task.realActivity != null) {
3816                    ActivityInfo ai = availActCache.get(task.realActivity);
3817                    if (ai == null) {
3818                        try {
3819                            ai = pm.getActivityInfo(task.realActivity,
3820                                    PackageManager.GET_UNINSTALLED_PACKAGES
3821                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3822                        } catch (RemoteException e) {
3823                            // Will never happen.
3824                            continue;
3825                        }
3826                        if (ai == null) {
3827                            ai = dummyAct;
3828                        }
3829                        availActCache.put(task.realActivity, ai);
3830                    }
3831                    if (ai == dummyAct) {
3832                        // This could be either because the activity no longer exists, or the
3833                        // app is temporarily gone.  For the former we want to remove the recents
3834                        // entry; for the latter we want to mark it as unavailable.
3835                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3836                        if (app == null) {
3837                            try {
3838                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3839                                        PackageManager.GET_UNINSTALLED_PACKAGES
3840                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3841                            } catch (RemoteException e) {
3842                                // Will never happen.
3843                                continue;
3844                            }
3845                            if (app == null) {
3846                                app = dummyApp;
3847                            }
3848                            availAppCache.put(task.realActivity.getPackageName(), app);
3849                        }
3850                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3851                            // Doesn't exist any more!  Good-bye.
3852                            mRecentTasks.remove(i);
3853                            task.removedFromRecents();
3854                            i--;
3855                            N--;
3856                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3857                            continue;
3858                        } else {
3859                            // Otherwise just not available for now.
3860                            if (task.isAvailable) {
3861                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3862                                        + task);
3863                            }
3864                            task.isAvailable = false;
3865                        }
3866                    } else {
3867                        if (!ai.enabled || !ai.applicationInfo.enabled
3868                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3869                            if (task.isAvailable) {
3870                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3871                                        + task + " (enabled=" + ai.enabled + "/"
3872                                        + ai.applicationInfo.enabled +  " flags="
3873                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3874                            }
3875                            task.isAvailable = false;
3876                        } else {
3877                            if (!task.isAvailable) {
3878                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3879                                        + task);
3880                            }
3881                            task.isAvailable = true;
3882                        }
3883                    }
3884                }
3885            }
3886        }
3887
3888        // Verify the affiliate chain for each task.
3889        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3890        }
3891
3892        mTmpRecents.clear();
3893        // mRecentTasks is now in sorted, affiliated order.
3894    }
3895
3896    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3897        int N = mRecentTasks.size();
3898        TaskRecord top = task;
3899        int topIndex = taskIndex;
3900        while (top.mNextAffiliate != null && topIndex > 0) {
3901            top = top.mNextAffiliate;
3902            topIndex--;
3903        }
3904        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3905                + topIndex + " from intial " + taskIndex);
3906        // Find the end of the chain, doing a sanity check along the way.
3907        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3908        int endIndex = topIndex;
3909        TaskRecord prev = top;
3910        while (endIndex < N) {
3911            TaskRecord cur = mRecentTasks.get(endIndex);
3912            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3913                    + endIndex + " " + cur);
3914            if (cur == top) {
3915                // Verify start of the chain.
3916                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3917                    Slog.wtf(TAG, "Bad chain @" + endIndex
3918                            + ": first task has next affiliate: " + prev);
3919                    sane = false;
3920                    break;
3921                }
3922            } else {
3923                // Verify middle of the chain's next points back to the one before.
3924                if (cur.mNextAffiliate != prev
3925                        || cur.mNextAffiliateTaskId != prev.taskId) {
3926                    Slog.wtf(TAG, "Bad chain @" + endIndex
3927                            + ": middle task " + cur + " @" + endIndex
3928                            + " has bad next affiliate "
3929                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3930                            + ", expected " + prev);
3931                    sane = false;
3932                    break;
3933                }
3934            }
3935            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3936                // Chain ends here.
3937                if (cur.mPrevAffiliate != null) {
3938                    Slog.wtf(TAG, "Bad chain @" + endIndex
3939                            + ": last task " + cur + " has previous affiliate "
3940                            + cur.mPrevAffiliate);
3941                    sane = false;
3942                }
3943                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3944                break;
3945            } else {
3946                // Verify middle of the chain's prev points to a valid item.
3947                if (cur.mPrevAffiliate == null) {
3948                    Slog.wtf(TAG, "Bad chain @" + endIndex
3949                            + ": task " + cur + " has previous affiliate "
3950                            + cur.mPrevAffiliate + " but should be id "
3951                            + cur.mPrevAffiliate);
3952                    sane = false;
3953                    break;
3954                }
3955            }
3956            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3957                Slog.wtf(TAG, "Bad chain @" + endIndex
3958                        + ": task " + cur + " has affiliated id "
3959                        + cur.mAffiliatedTaskId + " but should be "
3960                        + task.mAffiliatedTaskId);
3961                sane = false;
3962                break;
3963            }
3964            prev = cur;
3965            endIndex++;
3966            if (endIndex >= N) {
3967                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3968                        + ": last task " + prev);
3969                sane = false;
3970                break;
3971            }
3972        }
3973        if (sane) {
3974            if (endIndex < taskIndex) {
3975                Slog.wtf(TAG, "Bad chain @" + endIndex
3976                        + ": did not extend to task " + task + " @" + taskIndex);
3977                sane = false;
3978            }
3979        }
3980        if (sane) {
3981            // All looks good, we can just move all of the affiliated tasks
3982            // to the top.
3983            for (int i=topIndex; i<=endIndex; i++) {
3984                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3985                        + " from " + i + " to " + (i-topIndex));
3986                TaskRecord cur = mRecentTasks.remove(i);
3987                mRecentTasks.add(i-topIndex, cur);
3988            }
3989            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3990                    + " to " + endIndex);
3991            return true;
3992        }
3993
3994        // Whoops, couldn't do it.
3995        return false;
3996    }
3997
3998    final void addRecentTaskLocked(TaskRecord task) {
3999        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4000                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4001                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4002
4003        int N = mRecentTasks.size();
4004        // Quick case: check if the top-most recent task is the same.
4005        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4006            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4007            return;
4008        }
4009        // Another quick case: check if this is part of a set of affiliated
4010        // tasks that are at the top.
4011        if (isAffiliated && N > 0 && task.inRecents
4012                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4013            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4014                    + " at top when adding " + task);
4015            return;
4016        }
4017        // Another quick case: never add voice sessions.
4018        if (task.voiceSession != null) {
4019            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4020            return;
4021        }
4022
4023        boolean needAffiliationFix = false;
4024
4025        // Slightly less quick case: the task is already in recents, so all we need
4026        // to do is move it.
4027        if (task.inRecents) {
4028            int taskIndex = mRecentTasks.indexOf(task);
4029            if (taskIndex >= 0) {
4030                if (!isAffiliated) {
4031                    // Simple case: this is not an affiliated task, so we just move it to the front.
4032                    mRecentTasks.remove(taskIndex);
4033                    mRecentTasks.add(0, task);
4034                    notifyTaskPersisterLocked(task, false);
4035                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4036                            + " from " + taskIndex);
4037                    return;
4038                } else {
4039                    // More complicated: need to keep all affiliated tasks together.
4040                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4041                        // All went well.
4042                        return;
4043                    }
4044
4045                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4046                    // everything and then go through our general path of adding a new task.
4047                    needAffiliationFix = true;
4048                }
4049            } else {
4050                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4051                needAffiliationFix = true;
4052            }
4053        }
4054
4055        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4056        trimRecentsForTaskLocked(task, true);
4057
4058        N = mRecentTasks.size();
4059        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4060            final TaskRecord tr = mRecentTasks.remove(N - 1);
4061            tr.removedFromRecents();
4062            N--;
4063        }
4064        task.inRecents = true;
4065        if (!isAffiliated || needAffiliationFix) {
4066            // If this is a simple non-affiliated task, or we had some failure trying to
4067            // handle it as part of an affilated task, then just place it at the top.
4068            mRecentTasks.add(0, task);
4069        } else if (isAffiliated) {
4070            // If this is a new affiliated task, then move all of the affiliated tasks
4071            // to the front and insert this new one.
4072            TaskRecord other = task.mNextAffiliate;
4073            if (other == null) {
4074                other = task.mPrevAffiliate;
4075            }
4076            if (other != null) {
4077                int otherIndex = mRecentTasks.indexOf(other);
4078                if (otherIndex >= 0) {
4079                    // Insert new task at appropriate location.
4080                    int taskIndex;
4081                    if (other == task.mNextAffiliate) {
4082                        // We found the index of our next affiliation, which is who is
4083                        // before us in the list, so add after that point.
4084                        taskIndex = otherIndex+1;
4085                    } else {
4086                        // We found the index of our previous affiliation, which is who is
4087                        // after us in the list, so add at their position.
4088                        taskIndex = otherIndex;
4089                    }
4090                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4091                            + taskIndex + ": " + task);
4092                    mRecentTasks.add(taskIndex, task);
4093
4094                    // Now move everything to the front.
4095                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4096                        // All went well.
4097                        return;
4098                    }
4099
4100                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4101                    // everything and then go through our general path of adding a new task.
4102                    needAffiliationFix = true;
4103                } else {
4104                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4105                            + other);
4106                    needAffiliationFix = true;
4107                }
4108            } else {
4109                if (DEBUG_RECENTS) Slog.d(TAG,
4110                        "addRecent: adding affiliated task without next/prev:" + task);
4111                needAffiliationFix = true;
4112            }
4113        }
4114        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4115
4116        if (needAffiliationFix) {
4117            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4118            cleanupRecentTasksLocked(task.userId);
4119        }
4120    }
4121
4122    /**
4123     * If needed, remove oldest existing entries in recents that are for the same kind
4124     * of task as the given one.
4125     */
4126    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4127        int N = mRecentTasks.size();
4128        final Intent intent = task.intent;
4129        final boolean document = intent != null && intent.isDocument();
4130
4131        int maxRecents = task.maxRecents - 1;
4132        for (int i=0; i<N; i++) {
4133            final TaskRecord tr = mRecentTasks.get(i);
4134            if (task != tr) {
4135                if (task.userId != tr.userId) {
4136                    continue;
4137                }
4138                if (i > MAX_RECENT_BITMAPS) {
4139                    tr.freeLastThumbnail();
4140                }
4141                final Intent trIntent = tr.intent;
4142                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4143                    (intent == null || !intent.filterEquals(trIntent))) {
4144                    continue;
4145                }
4146                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4147                if (document && trIsDocument) {
4148                    // These are the same document activity (not necessarily the same doc).
4149                    if (maxRecents > 0) {
4150                        --maxRecents;
4151                        continue;
4152                    }
4153                    // Hit the maximum number of documents for this task. Fall through
4154                    // and remove this document from recents.
4155                } else if (document || trIsDocument) {
4156                    // Only one of these is a document. Not the droid we're looking for.
4157                    continue;
4158                }
4159            }
4160
4161            if (!doTrim) {
4162                // If the caller is not actually asking for a trim, just tell them we reached
4163                // a point where the trim would happen.
4164                return i;
4165            }
4166
4167            // Either task and tr are the same or, their affinities match or their intents match
4168            // and neither of them is a document, or they are documents using the same activity
4169            // and their maxRecents has been reached.
4170            tr.disposeThumbnail();
4171            mRecentTasks.remove(i);
4172            if (task != tr) {
4173                tr.removedFromRecents();
4174            }
4175            i--;
4176            N--;
4177            if (task.intent == null) {
4178                // If the new recent task we are adding is not fully
4179                // specified, then replace it with the existing recent task.
4180                task = tr;
4181            }
4182            notifyTaskPersisterLocked(tr, false);
4183        }
4184
4185        return -1;
4186    }
4187
4188    @Override
4189    public void reportActivityFullyDrawn(IBinder token) {
4190        synchronized (this) {
4191            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4192            if (r == null) {
4193                return;
4194            }
4195            r.reportFullyDrawnLocked();
4196        }
4197    }
4198
4199    @Override
4200    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4201        synchronized (this) {
4202            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4203            if (r == null) {
4204                return;
4205            }
4206            final long origId = Binder.clearCallingIdentity();
4207            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4208            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4209                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4210            if (config != null) {
4211                r.frozenBeforeDestroy = true;
4212                if (!updateConfigurationLocked(config, r, false, false)) {
4213                    mStackSupervisor.resumeTopActivitiesLocked();
4214                }
4215            }
4216            Binder.restoreCallingIdentity(origId);
4217        }
4218    }
4219
4220    @Override
4221    public int getRequestedOrientation(IBinder token) {
4222        synchronized (this) {
4223            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4224            if (r == null) {
4225                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4226            }
4227            return mWindowManager.getAppOrientation(r.appToken);
4228        }
4229    }
4230
4231    /**
4232     * This is the internal entry point for handling Activity.finish().
4233     *
4234     * @param token The Binder token referencing the Activity we want to finish.
4235     * @param resultCode Result code, if any, from this Activity.
4236     * @param resultData Result data (Intent), if any, from this Activity.
4237     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4238     *            the root Activity in the task.
4239     *
4240     * @return Returns true if the activity successfully finished, or false if it is still running.
4241     */
4242    @Override
4243    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4244            boolean finishTask) {
4245        // Refuse possible leaked file descriptors
4246        if (resultData != null && resultData.hasFileDescriptors() == true) {
4247            throw new IllegalArgumentException("File descriptors passed in Intent");
4248        }
4249
4250        synchronized(this) {
4251            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4252            if (r == null) {
4253                return true;
4254            }
4255            // Keep track of the root activity of the task before we finish it
4256            TaskRecord tr = r.task;
4257            ActivityRecord rootR = tr.getRootActivity();
4258            if (rootR == null) {
4259                Slog.w(TAG, "Finishing task with all activities already finished");
4260            }
4261            // Do not allow task to finish in Lock Task mode.
4262            if (tr == mStackSupervisor.mLockTaskModeTask) {
4263                if (rootR == r) {
4264                    Slog.i(TAG, "Not finishing task in lock task mode");
4265                    mStackSupervisor.showLockTaskToast();
4266                    return false;
4267                }
4268            }
4269            if (mController != null) {
4270                // Find the first activity that is not finishing.
4271                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4272                if (next != null) {
4273                    // ask watcher if this is allowed
4274                    boolean resumeOK = true;
4275                    try {
4276                        resumeOK = mController.activityResuming(next.packageName);
4277                    } catch (RemoteException e) {
4278                        mController = null;
4279                        Watchdog.getInstance().setActivityController(null);
4280                    }
4281
4282                    if (!resumeOK) {
4283                        Slog.i(TAG, "Not finishing activity because controller resumed");
4284                        return false;
4285                    }
4286                }
4287            }
4288            final long origId = Binder.clearCallingIdentity();
4289            try {
4290                boolean res;
4291                if (finishTask && r == rootR) {
4292                    // If requested, remove the task that is associated to this activity only if it
4293                    // was the root activity in the task. The result code and data is ignored
4294                    // because we don't support returning them across task boundaries.
4295                    res = removeTaskByIdLocked(tr.taskId, false);
4296                    if (!res) {
4297                        Slog.i(TAG, "Removing task failed to finish activity");
4298                    }
4299                } else {
4300                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4301                            resultData, "app-request", true);
4302                    if (!res) {
4303                        Slog.i(TAG, "Failed to finish by app-request");
4304                    }
4305                }
4306                return res;
4307            } finally {
4308                Binder.restoreCallingIdentity(origId);
4309            }
4310        }
4311    }
4312
4313    @Override
4314    public final void finishHeavyWeightApp() {
4315        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4316                != PackageManager.PERMISSION_GRANTED) {
4317            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4318                    + Binder.getCallingPid()
4319                    + ", uid=" + Binder.getCallingUid()
4320                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4321            Slog.w(TAG, msg);
4322            throw new SecurityException(msg);
4323        }
4324
4325        synchronized(this) {
4326            if (mHeavyWeightProcess == null) {
4327                return;
4328            }
4329
4330            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4331                    mHeavyWeightProcess.activities);
4332            for (int i=0; i<activities.size(); i++) {
4333                ActivityRecord r = activities.get(i);
4334                if (!r.finishing) {
4335                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4336                            null, "finish-heavy", true);
4337                }
4338            }
4339
4340            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4341                    mHeavyWeightProcess.userId, 0));
4342            mHeavyWeightProcess = null;
4343        }
4344    }
4345
4346    @Override
4347    public void crashApplication(int uid, int initialPid, String packageName,
4348            String message) {
4349        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4350                != PackageManager.PERMISSION_GRANTED) {
4351            String msg = "Permission Denial: crashApplication() from pid="
4352                    + Binder.getCallingPid()
4353                    + ", uid=" + Binder.getCallingUid()
4354                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4355            Slog.w(TAG, msg);
4356            throw new SecurityException(msg);
4357        }
4358
4359        synchronized(this) {
4360            ProcessRecord proc = null;
4361
4362            // Figure out which process to kill.  We don't trust that initialPid
4363            // still has any relation to current pids, so must scan through the
4364            // list.
4365            synchronized (mPidsSelfLocked) {
4366                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4367                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4368                    if (p.uid != uid) {
4369                        continue;
4370                    }
4371                    if (p.pid == initialPid) {
4372                        proc = p;
4373                        break;
4374                    }
4375                    if (p.pkgList.containsKey(packageName)) {
4376                        proc = p;
4377                    }
4378                }
4379            }
4380
4381            if (proc == null) {
4382                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4383                        + " initialPid=" + initialPid
4384                        + " packageName=" + packageName);
4385                return;
4386            }
4387
4388            if (proc.thread != null) {
4389                if (proc.pid == Process.myPid()) {
4390                    Log.w(TAG, "crashApplication: trying to crash self!");
4391                    return;
4392                }
4393                long ident = Binder.clearCallingIdentity();
4394                try {
4395                    proc.thread.scheduleCrash(message);
4396                } catch (RemoteException e) {
4397                }
4398                Binder.restoreCallingIdentity(ident);
4399            }
4400        }
4401    }
4402
4403    @Override
4404    public final void finishSubActivity(IBinder token, String resultWho,
4405            int requestCode) {
4406        synchronized(this) {
4407            final long origId = Binder.clearCallingIdentity();
4408            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4409            if (r != null) {
4410                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4411            }
4412            Binder.restoreCallingIdentity(origId);
4413        }
4414    }
4415
4416    @Override
4417    public boolean finishActivityAffinity(IBinder token) {
4418        synchronized(this) {
4419            final long origId = Binder.clearCallingIdentity();
4420            try {
4421                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4422
4423                ActivityRecord rootR = r.task.getRootActivity();
4424                // Do not allow task to finish in Lock Task mode.
4425                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4426                    if (rootR == r) {
4427                        mStackSupervisor.showLockTaskToast();
4428                        return false;
4429                    }
4430                }
4431                boolean res = false;
4432                if (r != null) {
4433                    res = r.task.stack.finishActivityAffinityLocked(r);
4434                }
4435                return res;
4436            } finally {
4437                Binder.restoreCallingIdentity(origId);
4438            }
4439        }
4440    }
4441
4442    @Override
4443    public void finishVoiceTask(IVoiceInteractionSession session) {
4444        synchronized(this) {
4445            final long origId = Binder.clearCallingIdentity();
4446            try {
4447                mStackSupervisor.finishVoiceTask(session);
4448            } finally {
4449                Binder.restoreCallingIdentity(origId);
4450            }
4451        }
4452
4453    }
4454
4455    @Override
4456    public boolean releaseActivityInstance(IBinder token) {
4457        synchronized(this) {
4458            final long origId = Binder.clearCallingIdentity();
4459            try {
4460                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4461                if (r.task == null || r.task.stack == null) {
4462                    return false;
4463                }
4464                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4465            } finally {
4466                Binder.restoreCallingIdentity(origId);
4467            }
4468        }
4469    }
4470
4471    @Override
4472    public void releaseSomeActivities(IApplicationThread appInt) {
4473        synchronized(this) {
4474            final long origId = Binder.clearCallingIdentity();
4475            try {
4476                ProcessRecord app = getRecordForAppLocked(appInt);
4477                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4478            } finally {
4479                Binder.restoreCallingIdentity(origId);
4480            }
4481        }
4482    }
4483
4484    @Override
4485    public boolean willActivityBeVisible(IBinder token) {
4486        synchronized(this) {
4487            ActivityStack stack = ActivityRecord.getStackLocked(token);
4488            if (stack != null) {
4489                return stack.willActivityBeVisibleLocked(token);
4490            }
4491            return false;
4492        }
4493    }
4494
4495    @Override
4496    public void overridePendingTransition(IBinder token, String packageName,
4497            int enterAnim, int exitAnim) {
4498        synchronized(this) {
4499            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4500            if (self == null) {
4501                return;
4502            }
4503
4504            final long origId = Binder.clearCallingIdentity();
4505
4506            if (self.state == ActivityState.RESUMED
4507                    || self.state == ActivityState.PAUSING) {
4508                mWindowManager.overridePendingAppTransition(packageName,
4509                        enterAnim, exitAnim, null);
4510            }
4511
4512            Binder.restoreCallingIdentity(origId);
4513        }
4514    }
4515
4516    /**
4517     * Main function for removing an existing process from the activity manager
4518     * as a result of that process going away.  Clears out all connections
4519     * to the process.
4520     */
4521    private final void handleAppDiedLocked(ProcessRecord app,
4522            boolean restarting, boolean allowRestart) {
4523        int pid = app.pid;
4524        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4525        if (!kept && !restarting) {
4526            removeLruProcessLocked(app);
4527            if (pid > 0) {
4528                ProcessList.remove(pid);
4529            }
4530        }
4531
4532        if (mProfileProc == app) {
4533            clearProfilerLocked();
4534        }
4535
4536        // Remove this application's activities from active lists.
4537        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4538
4539        app.activities.clear();
4540
4541        if (app.instrumentationClass != null) {
4542            Slog.w(TAG, "Crash of app " + app.processName
4543                  + " running instrumentation " + app.instrumentationClass);
4544            Bundle info = new Bundle();
4545            info.putString("shortMsg", "Process crashed.");
4546            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4547        }
4548
4549        if (!restarting) {
4550            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4551                // If there was nothing to resume, and we are not already
4552                // restarting this process, but there is a visible activity that
4553                // is hosted by the process...  then make sure all visible
4554                // activities are running, taking care of restarting this
4555                // process.
4556                if (hasVisibleActivities) {
4557                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4558                }
4559            }
4560        }
4561    }
4562
4563    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4564        IBinder threadBinder = thread.asBinder();
4565        // Find the application record.
4566        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4567            ProcessRecord rec = mLruProcesses.get(i);
4568            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4569                return i;
4570            }
4571        }
4572        return -1;
4573    }
4574
4575    final ProcessRecord getRecordForAppLocked(
4576            IApplicationThread thread) {
4577        if (thread == null) {
4578            return null;
4579        }
4580
4581        int appIndex = getLRURecordIndexForAppLocked(thread);
4582        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4583    }
4584
4585    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4586        // If there are no longer any background processes running,
4587        // and the app that died was not running instrumentation,
4588        // then tell everyone we are now low on memory.
4589        boolean haveBg = false;
4590        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4591            ProcessRecord rec = mLruProcesses.get(i);
4592            if (rec.thread != null
4593                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4594                haveBg = true;
4595                break;
4596            }
4597        }
4598
4599        if (!haveBg) {
4600            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4601            if (doReport) {
4602                long now = SystemClock.uptimeMillis();
4603                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4604                    doReport = false;
4605                } else {
4606                    mLastMemUsageReportTime = now;
4607                }
4608            }
4609            final ArrayList<ProcessMemInfo> memInfos
4610                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4611            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4612            long now = SystemClock.uptimeMillis();
4613            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4614                ProcessRecord rec = mLruProcesses.get(i);
4615                if (rec == dyingProc || rec.thread == null) {
4616                    continue;
4617                }
4618                if (doReport) {
4619                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4620                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4621                }
4622                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4623                    // The low memory report is overriding any current
4624                    // state for a GC request.  Make sure to do
4625                    // heavy/important/visible/foreground processes first.
4626                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4627                        rec.lastRequestedGc = 0;
4628                    } else {
4629                        rec.lastRequestedGc = rec.lastLowMemory;
4630                    }
4631                    rec.reportLowMemory = true;
4632                    rec.lastLowMemory = now;
4633                    mProcessesToGc.remove(rec);
4634                    addProcessToGcListLocked(rec);
4635                }
4636            }
4637            if (doReport) {
4638                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4639                mHandler.sendMessage(msg);
4640            }
4641            scheduleAppGcsLocked();
4642        }
4643    }
4644
4645    final void appDiedLocked(ProcessRecord app) {
4646       appDiedLocked(app, app.pid, app.thread);
4647    }
4648
4649    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4650        // First check if this ProcessRecord is actually active for the pid.
4651        synchronized (mPidsSelfLocked) {
4652            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4653            if (curProc != app) {
4654                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4655                return;
4656            }
4657        }
4658
4659        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4660        synchronized (stats) {
4661            stats.noteProcessDiedLocked(app.info.uid, pid);
4662        }
4663
4664        if (!app.killed) {
4665            Process.killProcessQuiet(pid);
4666            Process.killProcessGroup(app.info.uid, pid);
4667            app.killed = true;
4668        }
4669
4670        // Clean up already done if the process has been re-started.
4671        if (app.pid == pid && app.thread != null &&
4672                app.thread.asBinder() == thread.asBinder()) {
4673            boolean doLowMem = app.instrumentationClass == null;
4674            boolean doOomAdj = doLowMem;
4675            if (!app.killedByAm) {
4676                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4677                        + ") has died");
4678                mAllowLowerMemLevel = true;
4679            } else {
4680                // Note that we always want to do oom adj to update our state with the
4681                // new number of procs.
4682                mAllowLowerMemLevel = false;
4683                doLowMem = false;
4684            }
4685            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4686            if (DEBUG_CLEANUP) Slog.v(
4687                TAG, "Dying app: " + app + ", pid: " + pid
4688                + ", thread: " + thread.asBinder());
4689            handleAppDiedLocked(app, false, true);
4690
4691            if (doOomAdj) {
4692                updateOomAdjLocked();
4693            }
4694            if (doLowMem) {
4695                doLowMemReportIfNeededLocked(app);
4696            }
4697        } else if (app.pid != pid) {
4698            // A new process has already been started.
4699            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4700                    + ") has died and restarted (pid " + app.pid + ").");
4701            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4702        } else if (DEBUG_PROCESSES) {
4703            Slog.d(TAG, "Received spurious death notification for thread "
4704                    + thread.asBinder());
4705        }
4706    }
4707
4708    /**
4709     * If a stack trace dump file is configured, dump process stack traces.
4710     * @param clearTraces causes the dump file to be erased prior to the new
4711     *    traces being written, if true; when false, the new traces will be
4712     *    appended to any existing file content.
4713     * @param firstPids of dalvik VM processes to dump stack traces for first
4714     * @param lastPids of dalvik VM processes to dump stack traces for last
4715     * @param nativeProcs optional list of native process names to dump stack crawls
4716     * @return file containing stack traces, or null if no dump file is configured
4717     */
4718    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4719            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4720        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4721        if (tracesPath == null || tracesPath.length() == 0) {
4722            return null;
4723        }
4724
4725        File tracesFile = new File(tracesPath);
4726        try {
4727            File tracesDir = tracesFile.getParentFile();
4728            if (!tracesDir.exists()) {
4729                tracesDir.mkdirs();
4730                if (!SELinux.restorecon(tracesDir)) {
4731                    return null;
4732                }
4733            }
4734            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4735
4736            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4737            tracesFile.createNewFile();
4738            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4739        } catch (IOException e) {
4740            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4741            return null;
4742        }
4743
4744        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4745        return tracesFile;
4746    }
4747
4748    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4749            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4750        // Use a FileObserver to detect when traces finish writing.
4751        // The order of traces is considered important to maintain for legibility.
4752        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4753            @Override
4754            public synchronized void onEvent(int event, String path) { notify(); }
4755        };
4756
4757        try {
4758            observer.startWatching();
4759
4760            // First collect all of the stacks of the most important pids.
4761            if (firstPids != null) {
4762                try {
4763                    int num = firstPids.size();
4764                    for (int i = 0; i < num; i++) {
4765                        synchronized (observer) {
4766                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4767                            observer.wait(200);  // Wait for write-close, give up after 200msec
4768                        }
4769                    }
4770                } catch (InterruptedException e) {
4771                    Slog.wtf(TAG, e);
4772                }
4773            }
4774
4775            // Next collect the stacks of the native pids
4776            if (nativeProcs != null) {
4777                int[] pids = Process.getPidsForCommands(nativeProcs);
4778                if (pids != null) {
4779                    for (int pid : pids) {
4780                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4781                    }
4782                }
4783            }
4784
4785            // Lastly, measure CPU usage.
4786            if (processCpuTracker != null) {
4787                processCpuTracker.init();
4788                System.gc();
4789                processCpuTracker.update();
4790                try {
4791                    synchronized (processCpuTracker) {
4792                        processCpuTracker.wait(500); // measure over 1/2 second.
4793                    }
4794                } catch (InterruptedException e) {
4795                }
4796                processCpuTracker.update();
4797
4798                // We'll take the stack crawls of just the top apps using CPU.
4799                final int N = processCpuTracker.countWorkingStats();
4800                int numProcs = 0;
4801                for (int i=0; i<N && numProcs<5; i++) {
4802                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4803                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4804                        numProcs++;
4805                        try {
4806                            synchronized (observer) {
4807                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4808                                observer.wait(200);  // Wait for write-close, give up after 200msec
4809                            }
4810                        } catch (InterruptedException e) {
4811                            Slog.wtf(TAG, e);
4812                        }
4813
4814                    }
4815                }
4816            }
4817        } finally {
4818            observer.stopWatching();
4819        }
4820    }
4821
4822    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4823        if (true || IS_USER_BUILD) {
4824            return;
4825        }
4826        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4827        if (tracesPath == null || tracesPath.length() == 0) {
4828            return;
4829        }
4830
4831        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4832        StrictMode.allowThreadDiskWrites();
4833        try {
4834            final File tracesFile = new File(tracesPath);
4835            final File tracesDir = tracesFile.getParentFile();
4836            final File tracesTmp = new File(tracesDir, "__tmp__");
4837            try {
4838                if (!tracesDir.exists()) {
4839                    tracesDir.mkdirs();
4840                    if (!SELinux.restorecon(tracesDir.getPath())) {
4841                        return;
4842                    }
4843                }
4844                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4845
4846                if (tracesFile.exists()) {
4847                    tracesTmp.delete();
4848                    tracesFile.renameTo(tracesTmp);
4849                }
4850                StringBuilder sb = new StringBuilder();
4851                Time tobj = new Time();
4852                tobj.set(System.currentTimeMillis());
4853                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4854                sb.append(": ");
4855                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4856                sb.append(" since ");
4857                sb.append(msg);
4858                FileOutputStream fos = new FileOutputStream(tracesFile);
4859                fos.write(sb.toString().getBytes());
4860                if (app == null) {
4861                    fos.write("\n*** No application process!".getBytes());
4862                }
4863                fos.close();
4864                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4865            } catch (IOException e) {
4866                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4867                return;
4868            }
4869
4870            if (app != null) {
4871                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4872                firstPids.add(app.pid);
4873                dumpStackTraces(tracesPath, firstPids, null, null, null);
4874            }
4875
4876            File lastTracesFile = null;
4877            File curTracesFile = null;
4878            for (int i=9; i>=0; i--) {
4879                String name = String.format(Locale.US, "slow%02d.txt", i);
4880                curTracesFile = new File(tracesDir, name);
4881                if (curTracesFile.exists()) {
4882                    if (lastTracesFile != null) {
4883                        curTracesFile.renameTo(lastTracesFile);
4884                    } else {
4885                        curTracesFile.delete();
4886                    }
4887                }
4888                lastTracesFile = curTracesFile;
4889            }
4890            tracesFile.renameTo(curTracesFile);
4891            if (tracesTmp.exists()) {
4892                tracesTmp.renameTo(tracesFile);
4893            }
4894        } finally {
4895            StrictMode.setThreadPolicy(oldPolicy);
4896        }
4897    }
4898
4899    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4900            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4901        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4902        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4903
4904        if (mController != null) {
4905            try {
4906                // 0 == continue, -1 = kill process immediately
4907                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4908                if (res < 0 && app.pid != MY_PID) {
4909                    app.kill("anr", true);
4910                }
4911            } catch (RemoteException e) {
4912                mController = null;
4913                Watchdog.getInstance().setActivityController(null);
4914            }
4915        }
4916
4917        long anrTime = SystemClock.uptimeMillis();
4918        if (MONITOR_CPU_USAGE) {
4919            updateCpuStatsNow();
4920        }
4921
4922        synchronized (this) {
4923            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4924            if (mShuttingDown) {
4925                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4926                return;
4927            } else if (app.notResponding) {
4928                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4929                return;
4930            } else if (app.crashing) {
4931                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4932                return;
4933            }
4934
4935            // In case we come through here for the same app before completing
4936            // this one, mark as anring now so we will bail out.
4937            app.notResponding = true;
4938
4939            // Log the ANR to the event log.
4940            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4941                    app.processName, app.info.flags, annotation);
4942
4943            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4944            firstPids.add(app.pid);
4945
4946            int parentPid = app.pid;
4947            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4948            if (parentPid != app.pid) firstPids.add(parentPid);
4949
4950            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4951
4952            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4953                ProcessRecord r = mLruProcesses.get(i);
4954                if (r != null && r.thread != null) {
4955                    int pid = r.pid;
4956                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4957                        if (r.persistent) {
4958                            firstPids.add(pid);
4959                        } else {
4960                            lastPids.put(pid, Boolean.TRUE);
4961                        }
4962                    }
4963                }
4964            }
4965        }
4966
4967        // Log the ANR to the main log.
4968        StringBuilder info = new StringBuilder();
4969        info.setLength(0);
4970        info.append("ANR in ").append(app.processName);
4971        if (activity != null && activity.shortComponentName != null) {
4972            info.append(" (").append(activity.shortComponentName).append(")");
4973        }
4974        info.append("\n");
4975        info.append("PID: ").append(app.pid).append("\n");
4976        if (annotation != null) {
4977            info.append("Reason: ").append(annotation).append("\n");
4978        }
4979        if (parent != null && parent != activity) {
4980            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4981        }
4982
4983        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4984
4985        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4986                NATIVE_STACKS_OF_INTEREST);
4987
4988        String cpuInfo = null;
4989        if (MONITOR_CPU_USAGE) {
4990            updateCpuStatsNow();
4991            synchronized (mProcessCpuTracker) {
4992                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4993            }
4994            info.append(processCpuTracker.printCurrentLoad());
4995            info.append(cpuInfo);
4996        }
4997
4998        info.append(processCpuTracker.printCurrentState(anrTime));
4999
5000        Slog.e(TAG, info.toString());
5001        if (tracesFile == null) {
5002            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5003            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5004        }
5005
5006        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5007                cpuInfo, tracesFile, null);
5008
5009        if (mController != null) {
5010            try {
5011                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5012                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5013                if (res != 0) {
5014                    if (res < 0 && app.pid != MY_PID) {
5015                        app.kill("anr", true);
5016                    } else {
5017                        synchronized (this) {
5018                            mServices.scheduleServiceTimeoutLocked(app);
5019                        }
5020                    }
5021                    return;
5022                }
5023            } catch (RemoteException e) {
5024                mController = null;
5025                Watchdog.getInstance().setActivityController(null);
5026            }
5027        }
5028
5029        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5030        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5031                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5032
5033        synchronized (this) {
5034            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5035
5036            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5037                app.kill("bg anr", true);
5038                return;
5039            }
5040
5041            // Set the app's notResponding state, and look up the errorReportReceiver
5042            makeAppNotRespondingLocked(app,
5043                    activity != null ? activity.shortComponentName : null,
5044                    annotation != null ? "ANR " + annotation : "ANR",
5045                    info.toString());
5046
5047            // Bring up the infamous App Not Responding dialog
5048            Message msg = Message.obtain();
5049            HashMap<String, Object> map = new HashMap<String, Object>();
5050            msg.what = SHOW_NOT_RESPONDING_MSG;
5051            msg.obj = map;
5052            msg.arg1 = aboveSystem ? 1 : 0;
5053            map.put("app", app);
5054            if (activity != null) {
5055                map.put("activity", activity);
5056            }
5057
5058            mHandler.sendMessage(msg);
5059        }
5060    }
5061
5062    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5063        if (!mLaunchWarningShown) {
5064            mLaunchWarningShown = true;
5065            mHandler.post(new Runnable() {
5066                @Override
5067                public void run() {
5068                    synchronized (ActivityManagerService.this) {
5069                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5070                        d.show();
5071                        mHandler.postDelayed(new Runnable() {
5072                            @Override
5073                            public void run() {
5074                                synchronized (ActivityManagerService.this) {
5075                                    d.dismiss();
5076                                    mLaunchWarningShown = false;
5077                                }
5078                            }
5079                        }, 4000);
5080                    }
5081                }
5082            });
5083        }
5084    }
5085
5086    @Override
5087    public boolean clearApplicationUserData(final String packageName,
5088            final IPackageDataObserver observer, int userId) {
5089        enforceNotIsolatedCaller("clearApplicationUserData");
5090        int uid = Binder.getCallingUid();
5091        int pid = Binder.getCallingPid();
5092        userId = handleIncomingUser(pid, uid,
5093                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5094        long callingId = Binder.clearCallingIdentity();
5095        try {
5096            IPackageManager pm = AppGlobals.getPackageManager();
5097            int pkgUid = -1;
5098            synchronized(this) {
5099                try {
5100                    pkgUid = pm.getPackageUid(packageName, userId);
5101                } catch (RemoteException e) {
5102                }
5103                if (pkgUid == -1) {
5104                    Slog.w(TAG, "Invalid packageName: " + packageName);
5105                    if (observer != null) {
5106                        try {
5107                            observer.onRemoveCompleted(packageName, false);
5108                        } catch (RemoteException e) {
5109                            Slog.i(TAG, "Observer no longer exists.");
5110                        }
5111                    }
5112                    return false;
5113                }
5114                if (uid == pkgUid || checkComponentPermission(
5115                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5116                        pid, uid, -1, true)
5117                        == PackageManager.PERMISSION_GRANTED) {
5118                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5119                } else {
5120                    throw new SecurityException("PID " + pid + " does not have permission "
5121                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5122                                    + " of package " + packageName);
5123                }
5124
5125                // Remove all tasks match the cleared application package and user
5126                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5127                    final TaskRecord tr = mRecentTasks.get(i);
5128                    final String taskPackageName =
5129                            tr.getBaseIntent().getComponent().getPackageName();
5130                    if (tr.userId != userId) continue;
5131                    if (!taskPackageName.equals(packageName)) continue;
5132                    removeTaskByIdLocked(tr.taskId, false);
5133                }
5134            }
5135
5136            try {
5137                // Clear application user data
5138                pm.clearApplicationUserData(packageName, observer, userId);
5139
5140                synchronized(this) {
5141                    // Remove all permissions granted from/to this package
5142                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5143                }
5144
5145                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5146                        Uri.fromParts("package", packageName, null));
5147                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5148                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5149                        null, null, 0, null, null, null, false, false, userId);
5150            } catch (RemoteException e) {
5151            }
5152        } finally {
5153            Binder.restoreCallingIdentity(callingId);
5154        }
5155        return true;
5156    }
5157
5158    @Override
5159    public void killBackgroundProcesses(final String packageName, int userId) {
5160        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5161                != PackageManager.PERMISSION_GRANTED &&
5162                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5163                        != PackageManager.PERMISSION_GRANTED) {
5164            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5165                    + Binder.getCallingPid()
5166                    + ", uid=" + Binder.getCallingUid()
5167                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5168            Slog.w(TAG, msg);
5169            throw new SecurityException(msg);
5170        }
5171
5172        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5173                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5174        long callingId = Binder.clearCallingIdentity();
5175        try {
5176            IPackageManager pm = AppGlobals.getPackageManager();
5177            synchronized(this) {
5178                int appId = -1;
5179                try {
5180                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5181                } catch (RemoteException e) {
5182                }
5183                if (appId == -1) {
5184                    Slog.w(TAG, "Invalid packageName: " + packageName);
5185                    return;
5186                }
5187                killPackageProcessesLocked(packageName, appId, userId,
5188                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5189            }
5190        } finally {
5191            Binder.restoreCallingIdentity(callingId);
5192        }
5193    }
5194
5195    @Override
5196    public void killAllBackgroundProcesses() {
5197        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5198                != PackageManager.PERMISSION_GRANTED) {
5199            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5200                    + Binder.getCallingPid()
5201                    + ", uid=" + Binder.getCallingUid()
5202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5203            Slog.w(TAG, msg);
5204            throw new SecurityException(msg);
5205        }
5206
5207        long callingId = Binder.clearCallingIdentity();
5208        try {
5209            synchronized(this) {
5210                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5211                final int NP = mProcessNames.getMap().size();
5212                for (int ip=0; ip<NP; ip++) {
5213                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5214                    final int NA = apps.size();
5215                    for (int ia=0; ia<NA; ia++) {
5216                        ProcessRecord app = apps.valueAt(ia);
5217                        if (app.persistent) {
5218                            // we don't kill persistent processes
5219                            continue;
5220                        }
5221                        if (app.removed) {
5222                            procs.add(app);
5223                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5224                            app.removed = true;
5225                            procs.add(app);
5226                        }
5227                    }
5228                }
5229
5230                int N = procs.size();
5231                for (int i=0; i<N; i++) {
5232                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5233                }
5234                mAllowLowerMemLevel = true;
5235                updateOomAdjLocked();
5236                doLowMemReportIfNeededLocked(null);
5237            }
5238        } finally {
5239            Binder.restoreCallingIdentity(callingId);
5240        }
5241    }
5242
5243    @Override
5244    public void forceStopPackage(final String packageName, int userId) {
5245        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5246                != PackageManager.PERMISSION_GRANTED) {
5247            String msg = "Permission Denial: forceStopPackage() from pid="
5248                    + Binder.getCallingPid()
5249                    + ", uid=" + Binder.getCallingUid()
5250                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5251            Slog.w(TAG, msg);
5252            throw new SecurityException(msg);
5253        }
5254        final int callingPid = Binder.getCallingPid();
5255        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5256                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5257        long callingId = Binder.clearCallingIdentity();
5258        try {
5259            IPackageManager pm = AppGlobals.getPackageManager();
5260            synchronized(this) {
5261                int[] users = userId == UserHandle.USER_ALL
5262                        ? getUsersLocked() : new int[] { userId };
5263                for (int user : users) {
5264                    int pkgUid = -1;
5265                    try {
5266                        pkgUid = pm.getPackageUid(packageName, user);
5267                    } catch (RemoteException e) {
5268                    }
5269                    if (pkgUid == -1) {
5270                        Slog.w(TAG, "Invalid packageName: " + packageName);
5271                        continue;
5272                    }
5273                    try {
5274                        pm.setPackageStoppedState(packageName, true, user);
5275                    } catch (RemoteException e) {
5276                    } catch (IllegalArgumentException e) {
5277                        Slog.w(TAG, "Failed trying to unstop package "
5278                                + packageName + ": " + e);
5279                    }
5280                    if (isUserRunningLocked(user, false)) {
5281                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5282                    }
5283                }
5284            }
5285        } finally {
5286            Binder.restoreCallingIdentity(callingId);
5287        }
5288    }
5289
5290    @Override
5291    public void addPackageDependency(String packageName) {
5292        synchronized (this) {
5293            int callingPid = Binder.getCallingPid();
5294            if (callingPid == Process.myPid()) {
5295                //  Yeah, um, no.
5296                Slog.w(TAG, "Can't addPackageDependency on system process");
5297                return;
5298            }
5299            ProcessRecord proc;
5300            synchronized (mPidsSelfLocked) {
5301                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5302            }
5303            if (proc != null) {
5304                if (proc.pkgDeps == null) {
5305                    proc.pkgDeps = new ArraySet<String>(1);
5306                }
5307                proc.pkgDeps.add(packageName);
5308            }
5309        }
5310    }
5311
5312    /*
5313     * The pkg name and app id have to be specified.
5314     */
5315    @Override
5316    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5317        if (pkg == null) {
5318            return;
5319        }
5320        // Make sure the uid is valid.
5321        if (appid < 0) {
5322            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5323            return;
5324        }
5325        int callerUid = Binder.getCallingUid();
5326        // Only the system server can kill an application
5327        if (callerUid == Process.SYSTEM_UID) {
5328            // Post an aysnc message to kill the application
5329            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5330            msg.arg1 = appid;
5331            msg.arg2 = 0;
5332            Bundle bundle = new Bundle();
5333            bundle.putString("pkg", pkg);
5334            bundle.putString("reason", reason);
5335            msg.obj = bundle;
5336            mHandler.sendMessage(msg);
5337        } else {
5338            throw new SecurityException(callerUid + " cannot kill pkg: " +
5339                    pkg);
5340        }
5341    }
5342
5343    @Override
5344    public void closeSystemDialogs(String reason) {
5345        enforceNotIsolatedCaller("closeSystemDialogs");
5346
5347        final int pid = Binder.getCallingPid();
5348        final int uid = Binder.getCallingUid();
5349        final long origId = Binder.clearCallingIdentity();
5350        try {
5351            synchronized (this) {
5352                // Only allow this from foreground processes, so that background
5353                // applications can't abuse it to prevent system UI from being shown.
5354                if (uid >= Process.FIRST_APPLICATION_UID) {
5355                    ProcessRecord proc;
5356                    synchronized (mPidsSelfLocked) {
5357                        proc = mPidsSelfLocked.get(pid);
5358                    }
5359                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5360                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5361                                + " from background process " + proc);
5362                        return;
5363                    }
5364                }
5365                closeSystemDialogsLocked(reason);
5366            }
5367        } finally {
5368            Binder.restoreCallingIdentity(origId);
5369        }
5370    }
5371
5372    void closeSystemDialogsLocked(String reason) {
5373        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5374        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5375                | Intent.FLAG_RECEIVER_FOREGROUND);
5376        if (reason != null) {
5377            intent.putExtra("reason", reason);
5378        }
5379        mWindowManager.closeSystemDialogs(reason);
5380
5381        mStackSupervisor.closeSystemDialogsLocked();
5382
5383        broadcastIntentLocked(null, null, intent, null,
5384                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5385                Process.SYSTEM_UID, UserHandle.USER_ALL);
5386    }
5387
5388    @Override
5389    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5390        enforceNotIsolatedCaller("getProcessMemoryInfo");
5391        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5392        for (int i=pids.length-1; i>=0; i--) {
5393            ProcessRecord proc;
5394            int oomAdj;
5395            synchronized (this) {
5396                synchronized (mPidsSelfLocked) {
5397                    proc = mPidsSelfLocked.get(pids[i]);
5398                    oomAdj = proc != null ? proc.setAdj : 0;
5399                }
5400            }
5401            infos[i] = new Debug.MemoryInfo();
5402            Debug.getMemoryInfo(pids[i], infos[i]);
5403            if (proc != null) {
5404                synchronized (this) {
5405                    if (proc.thread != null && proc.setAdj == oomAdj) {
5406                        // Record this for posterity if the process has been stable.
5407                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5408                                infos[i].getTotalUss(), false, proc.pkgList);
5409                    }
5410                }
5411            }
5412        }
5413        return infos;
5414    }
5415
5416    @Override
5417    public long[] getProcessPss(int[] pids) {
5418        enforceNotIsolatedCaller("getProcessPss");
5419        long[] pss = new long[pids.length];
5420        for (int i=pids.length-1; i>=0; i--) {
5421            ProcessRecord proc;
5422            int oomAdj;
5423            synchronized (this) {
5424                synchronized (mPidsSelfLocked) {
5425                    proc = mPidsSelfLocked.get(pids[i]);
5426                    oomAdj = proc != null ? proc.setAdj : 0;
5427                }
5428            }
5429            long[] tmpUss = new long[1];
5430            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5431            if (proc != null) {
5432                synchronized (this) {
5433                    if (proc.thread != null && proc.setAdj == oomAdj) {
5434                        // Record this for posterity if the process has been stable.
5435                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5436                    }
5437                }
5438            }
5439        }
5440        return pss;
5441    }
5442
5443    @Override
5444    public void killApplicationProcess(String processName, int uid) {
5445        if (processName == null) {
5446            return;
5447        }
5448
5449        int callerUid = Binder.getCallingUid();
5450        // Only the system server can kill an application
5451        if (callerUid == Process.SYSTEM_UID) {
5452            synchronized (this) {
5453                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5454                if (app != null && app.thread != null) {
5455                    try {
5456                        app.thread.scheduleSuicide();
5457                    } catch (RemoteException e) {
5458                        // If the other end already died, then our work here is done.
5459                    }
5460                } else {
5461                    Slog.w(TAG, "Process/uid not found attempting kill of "
5462                            + processName + " / " + uid);
5463                }
5464            }
5465        } else {
5466            throw new SecurityException(callerUid + " cannot kill app process: " +
5467                    processName);
5468        }
5469    }
5470
5471    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5472        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5473                false, true, false, false, UserHandle.getUserId(uid), reason);
5474        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5475                Uri.fromParts("package", packageName, null));
5476        if (!mProcessesReady) {
5477            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5478                    | Intent.FLAG_RECEIVER_FOREGROUND);
5479        }
5480        intent.putExtra(Intent.EXTRA_UID, uid);
5481        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5482        broadcastIntentLocked(null, null, intent,
5483                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5484                false, false,
5485                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5486    }
5487
5488    private void forceStopUserLocked(int userId, String reason) {
5489        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5490        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5491        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5492                | Intent.FLAG_RECEIVER_FOREGROUND);
5493        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5494        broadcastIntentLocked(null, null, intent,
5495                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5496                false, false,
5497                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5498    }
5499
5500    private final boolean killPackageProcessesLocked(String packageName, int appId,
5501            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5502            boolean doit, boolean evenPersistent, String reason) {
5503        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5504
5505        // Remove all processes this package may have touched: all with the
5506        // same UID (except for the system or root user), and all whose name
5507        // matches the package name.
5508        final int NP = mProcessNames.getMap().size();
5509        for (int ip=0; ip<NP; ip++) {
5510            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5511            final int NA = apps.size();
5512            for (int ia=0; ia<NA; ia++) {
5513                ProcessRecord app = apps.valueAt(ia);
5514                if (app.persistent && !evenPersistent) {
5515                    // we don't kill persistent processes
5516                    continue;
5517                }
5518                if (app.removed) {
5519                    if (doit) {
5520                        procs.add(app);
5521                    }
5522                    continue;
5523                }
5524
5525                // Skip process if it doesn't meet our oom adj requirement.
5526                if (app.setAdj < minOomAdj) {
5527                    continue;
5528                }
5529
5530                // If no package is specified, we call all processes under the
5531                // give user id.
5532                if (packageName == null) {
5533                    if (app.userId != userId) {
5534                        continue;
5535                    }
5536                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5537                        continue;
5538                    }
5539                // Package has been specified, we want to hit all processes
5540                // that match it.  We need to qualify this by the processes
5541                // that are running under the specified app and user ID.
5542                } else {
5543                    final boolean isDep = app.pkgDeps != null
5544                            && app.pkgDeps.contains(packageName);
5545                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5546                        continue;
5547                    }
5548                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5549                        continue;
5550                    }
5551                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5552                        continue;
5553                    }
5554                }
5555
5556                // Process has passed all conditions, kill it!
5557                if (!doit) {
5558                    return true;
5559                }
5560                app.removed = true;
5561                procs.add(app);
5562            }
5563        }
5564
5565        int N = procs.size();
5566        for (int i=0; i<N; i++) {
5567            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5568        }
5569        updateOomAdjLocked();
5570        return N > 0;
5571    }
5572
5573    private final boolean forceStopPackageLocked(String name, int appId,
5574            boolean callerWillRestart, boolean purgeCache, boolean doit,
5575            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5576        int i;
5577        int N;
5578
5579        if (userId == UserHandle.USER_ALL && name == null) {
5580            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5581        }
5582
5583        if (appId < 0 && name != null) {
5584            try {
5585                appId = UserHandle.getAppId(
5586                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5587            } catch (RemoteException e) {
5588            }
5589        }
5590
5591        if (doit) {
5592            if (name != null) {
5593                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5594                        + " user=" + userId + ": " + reason);
5595            } else {
5596                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5597            }
5598
5599            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5600            for (int ip=pmap.size()-1; ip>=0; ip--) {
5601                SparseArray<Long> ba = pmap.valueAt(ip);
5602                for (i=ba.size()-1; i>=0; i--) {
5603                    boolean remove = false;
5604                    final int entUid = ba.keyAt(i);
5605                    if (name != null) {
5606                        if (userId == UserHandle.USER_ALL) {
5607                            if (UserHandle.getAppId(entUid) == appId) {
5608                                remove = true;
5609                            }
5610                        } else {
5611                            if (entUid == UserHandle.getUid(userId, appId)) {
5612                                remove = true;
5613                            }
5614                        }
5615                    } else if (UserHandle.getUserId(entUid) == userId) {
5616                        remove = true;
5617                    }
5618                    if (remove) {
5619                        ba.removeAt(i);
5620                    }
5621                }
5622                if (ba.size() == 0) {
5623                    pmap.removeAt(ip);
5624                }
5625            }
5626        }
5627
5628        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5629                -100, callerWillRestart, true, doit, evenPersistent,
5630                name == null ? ("stop user " + userId) : ("stop " + name));
5631
5632        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5633            if (!doit) {
5634                return true;
5635            }
5636            didSomething = true;
5637        }
5638
5639        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5640            if (!doit) {
5641                return true;
5642            }
5643            didSomething = true;
5644        }
5645
5646        if (name == null) {
5647            // Remove all sticky broadcasts from this user.
5648            mStickyBroadcasts.remove(userId);
5649        }
5650
5651        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5652        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5653                userId, providers)) {
5654            if (!doit) {
5655                return true;
5656            }
5657            didSomething = true;
5658        }
5659        N = providers.size();
5660        for (i=0; i<N; i++) {
5661            removeDyingProviderLocked(null, providers.get(i), true);
5662        }
5663
5664        // Remove transient permissions granted from/to this package/user
5665        removeUriPermissionsForPackageLocked(name, userId, false);
5666
5667        if (name == null || uninstalling) {
5668            // Remove pending intents.  For now we only do this when force
5669            // stopping users, because we have some problems when doing this
5670            // for packages -- app widgets are not currently cleaned up for
5671            // such packages, so they can be left with bad pending intents.
5672            if (mIntentSenderRecords.size() > 0) {
5673                Iterator<WeakReference<PendingIntentRecord>> it
5674                        = mIntentSenderRecords.values().iterator();
5675                while (it.hasNext()) {
5676                    WeakReference<PendingIntentRecord> wpir = it.next();
5677                    if (wpir == null) {
5678                        it.remove();
5679                        continue;
5680                    }
5681                    PendingIntentRecord pir = wpir.get();
5682                    if (pir == null) {
5683                        it.remove();
5684                        continue;
5685                    }
5686                    if (name == null) {
5687                        // Stopping user, remove all objects for the user.
5688                        if (pir.key.userId != userId) {
5689                            // Not the same user, skip it.
5690                            continue;
5691                        }
5692                    } else {
5693                        if (UserHandle.getAppId(pir.uid) != appId) {
5694                            // Different app id, skip it.
5695                            continue;
5696                        }
5697                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5698                            // Different user, skip it.
5699                            continue;
5700                        }
5701                        if (!pir.key.packageName.equals(name)) {
5702                            // Different package, skip it.
5703                            continue;
5704                        }
5705                    }
5706                    if (!doit) {
5707                        return true;
5708                    }
5709                    didSomething = true;
5710                    it.remove();
5711                    pir.canceled = true;
5712                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5713                        pir.key.activity.pendingResults.remove(pir.ref);
5714                    }
5715                }
5716            }
5717        }
5718
5719        if (doit) {
5720            if (purgeCache && name != null) {
5721                AttributeCache ac = AttributeCache.instance();
5722                if (ac != null) {
5723                    ac.removePackage(name);
5724                }
5725            }
5726            if (mBooted) {
5727                mStackSupervisor.resumeTopActivitiesLocked();
5728                mStackSupervisor.scheduleIdleLocked();
5729            }
5730        }
5731
5732        return didSomething;
5733    }
5734
5735    private final boolean removeProcessLocked(ProcessRecord app,
5736            boolean callerWillRestart, boolean allowRestart, String reason) {
5737        final String name = app.processName;
5738        final int uid = app.uid;
5739        if (DEBUG_PROCESSES) Slog.d(
5740            TAG, "Force removing proc " + app.toShortString() + " (" + name
5741            + "/" + uid + ")");
5742
5743        mProcessNames.remove(name, uid);
5744        mIsolatedProcesses.remove(app.uid);
5745        if (mHeavyWeightProcess == app) {
5746            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5747                    mHeavyWeightProcess.userId, 0));
5748            mHeavyWeightProcess = null;
5749        }
5750        boolean needRestart = false;
5751        if (app.pid > 0 && app.pid != MY_PID) {
5752            int pid = app.pid;
5753            synchronized (mPidsSelfLocked) {
5754                mPidsSelfLocked.remove(pid);
5755                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5756            }
5757            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5758            if (app.isolated) {
5759                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5760            }
5761            app.kill(reason, true);
5762            handleAppDiedLocked(app, true, allowRestart);
5763            removeLruProcessLocked(app);
5764
5765            if (app.persistent && !app.isolated) {
5766                if (!callerWillRestart) {
5767                    addAppLocked(app.info, false, null /* ABI override */);
5768                } else {
5769                    needRestart = true;
5770                }
5771            }
5772        } else {
5773            mRemovedProcesses.add(app);
5774        }
5775
5776        return needRestart;
5777    }
5778
5779    private final void processStartTimedOutLocked(ProcessRecord app) {
5780        final int pid = app.pid;
5781        boolean gone = false;
5782        synchronized (mPidsSelfLocked) {
5783            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5784            if (knownApp != null && knownApp.thread == null) {
5785                mPidsSelfLocked.remove(pid);
5786                gone = true;
5787            }
5788        }
5789
5790        if (gone) {
5791            Slog.w(TAG, "Process " + app + " failed to attach");
5792            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5793                    pid, app.uid, app.processName);
5794            mProcessNames.remove(app.processName, app.uid);
5795            mIsolatedProcesses.remove(app.uid);
5796            if (mHeavyWeightProcess == app) {
5797                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5798                        mHeavyWeightProcess.userId, 0));
5799                mHeavyWeightProcess = null;
5800            }
5801            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5802            if (app.isolated) {
5803                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5804            }
5805            // Take care of any launching providers waiting for this process.
5806            checkAppInLaunchingProvidersLocked(app, true);
5807            // Take care of any services that are waiting for the process.
5808            mServices.processStartTimedOutLocked(app);
5809            app.kill("start timeout", true);
5810            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5811                Slog.w(TAG, "Unattached app died before backup, skipping");
5812                try {
5813                    IBackupManager bm = IBackupManager.Stub.asInterface(
5814                            ServiceManager.getService(Context.BACKUP_SERVICE));
5815                    bm.agentDisconnected(app.info.packageName);
5816                } catch (RemoteException e) {
5817                    // Can't happen; the backup manager is local
5818                }
5819            }
5820            if (isPendingBroadcastProcessLocked(pid)) {
5821                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5822                skipPendingBroadcastLocked(pid);
5823            }
5824        } else {
5825            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5826        }
5827    }
5828
5829    private final boolean attachApplicationLocked(IApplicationThread thread,
5830            int pid) {
5831
5832        // Find the application record that is being attached...  either via
5833        // the pid if we are running in multiple processes, or just pull the
5834        // next app record if we are emulating process with anonymous threads.
5835        ProcessRecord app;
5836        if (pid != MY_PID && pid >= 0) {
5837            synchronized (mPidsSelfLocked) {
5838                app = mPidsSelfLocked.get(pid);
5839            }
5840        } else {
5841            app = null;
5842        }
5843
5844        if (app == null) {
5845            Slog.w(TAG, "No pending application record for pid " + pid
5846                    + " (IApplicationThread " + thread + "); dropping process");
5847            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5848            if (pid > 0 && pid != MY_PID) {
5849                Process.killProcessQuiet(pid);
5850                //TODO: Process.killProcessGroup(app.info.uid, pid);
5851            } else {
5852                try {
5853                    thread.scheduleExit();
5854                } catch (Exception e) {
5855                    // Ignore exceptions.
5856                }
5857            }
5858            return false;
5859        }
5860
5861        // If this application record is still attached to a previous
5862        // process, clean it up now.
5863        if (app.thread != null) {
5864            handleAppDiedLocked(app, true, true);
5865        }
5866
5867        // Tell the process all about itself.
5868
5869        if (localLOGV) Slog.v(
5870                TAG, "Binding process pid " + pid + " to record " + app);
5871
5872        final String processName = app.processName;
5873        try {
5874            AppDeathRecipient adr = new AppDeathRecipient(
5875                    app, pid, thread);
5876            thread.asBinder().linkToDeath(adr, 0);
5877            app.deathRecipient = adr;
5878        } catch (RemoteException e) {
5879            app.resetPackageList(mProcessStats);
5880            startProcessLocked(app, "link fail", processName);
5881            return false;
5882        }
5883
5884        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5885
5886        app.makeActive(thread, mProcessStats);
5887        app.curAdj = app.setAdj = -100;
5888        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5889        app.forcingToForeground = null;
5890        updateProcessForegroundLocked(app, false, false);
5891        app.hasShownUi = false;
5892        app.debugging = false;
5893        app.cached = false;
5894        app.killedByAm = false;
5895
5896        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5897
5898        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5899        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5900
5901        if (!normalMode) {
5902            Slog.i(TAG, "Launching preboot mode app: " + app);
5903        }
5904
5905        if (localLOGV) Slog.v(
5906            TAG, "New app record " + app
5907            + " thread=" + thread.asBinder() + " pid=" + pid);
5908        try {
5909            int testMode = IApplicationThread.DEBUG_OFF;
5910            if (mDebugApp != null && mDebugApp.equals(processName)) {
5911                testMode = mWaitForDebugger
5912                    ? IApplicationThread.DEBUG_WAIT
5913                    : IApplicationThread.DEBUG_ON;
5914                app.debugging = true;
5915                if (mDebugTransient) {
5916                    mDebugApp = mOrigDebugApp;
5917                    mWaitForDebugger = mOrigWaitForDebugger;
5918                }
5919            }
5920            String profileFile = app.instrumentationProfileFile;
5921            ParcelFileDescriptor profileFd = null;
5922            int samplingInterval = 0;
5923            boolean profileAutoStop = false;
5924            if (mProfileApp != null && mProfileApp.equals(processName)) {
5925                mProfileProc = app;
5926                profileFile = mProfileFile;
5927                profileFd = mProfileFd;
5928                samplingInterval = mSamplingInterval;
5929                profileAutoStop = mAutoStopProfiler;
5930            }
5931            boolean enableOpenGlTrace = false;
5932            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5933                enableOpenGlTrace = true;
5934                mOpenGlTraceApp = null;
5935            }
5936
5937            // If the app is being launched for restore or full backup, set it up specially
5938            boolean isRestrictedBackupMode = false;
5939            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5940                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5941                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5942                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5943            }
5944
5945            ensurePackageDexOpt(app.instrumentationInfo != null
5946                    ? app.instrumentationInfo.packageName
5947                    : app.info.packageName);
5948            if (app.instrumentationClass != null) {
5949                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5950            }
5951            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5952                    + processName + " with config " + mConfiguration);
5953            ApplicationInfo appInfo = app.instrumentationInfo != null
5954                    ? app.instrumentationInfo : app.info;
5955            app.compat = compatibilityInfoForPackageLocked(appInfo);
5956            if (profileFd != null) {
5957                profileFd = profileFd.dup();
5958            }
5959            ProfilerInfo profilerInfo = profileFile == null ? null
5960                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5961            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5962                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5963                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5964                    isRestrictedBackupMode || !normalMode, app.persistent,
5965                    new Configuration(mConfiguration), app.compat,
5966                    getCommonServicesLocked(app.isolated),
5967                    mCoreSettingsObserver.getCoreSettingsLocked());
5968            updateLruProcessLocked(app, false, null);
5969            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5970        } catch (Exception e) {
5971            // todo: Yikes!  What should we do?  For now we will try to
5972            // start another process, but that could easily get us in
5973            // an infinite loop of restarting processes...
5974            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5975
5976            app.resetPackageList(mProcessStats);
5977            app.unlinkDeathRecipient();
5978            startProcessLocked(app, "bind fail", processName);
5979            return false;
5980        }
5981
5982        // Remove this record from the list of starting applications.
5983        mPersistentStartingProcesses.remove(app);
5984        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5985                "Attach application locked removing on hold: " + app);
5986        mProcessesOnHold.remove(app);
5987
5988        boolean badApp = false;
5989        boolean didSomething = false;
5990
5991        // See if the top visible activity is waiting to run in this process...
5992        if (normalMode) {
5993            try {
5994                if (mStackSupervisor.attachApplicationLocked(app)) {
5995                    didSomething = true;
5996                }
5997            } catch (Exception e) {
5998                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5999                badApp = true;
6000            }
6001        }
6002
6003        // Find any services that should be running in this process...
6004        if (!badApp) {
6005            try {
6006                didSomething |= mServices.attachApplicationLocked(app, processName);
6007            } catch (Exception e) {
6008                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6009                badApp = true;
6010            }
6011        }
6012
6013        // Check if a next-broadcast receiver is in this process...
6014        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6015            try {
6016                didSomething |= sendPendingBroadcastsLocked(app);
6017            } catch (Exception e) {
6018                // If the app died trying to launch the receiver we declare it 'bad'
6019                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6020                badApp = true;
6021            }
6022        }
6023
6024        // Check whether the next backup agent is in this process...
6025        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6026            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6027            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6028            try {
6029                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6030                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6031                        mBackupTarget.backupMode);
6032            } catch (Exception e) {
6033                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6034                badApp = true;
6035            }
6036        }
6037
6038        if (badApp) {
6039            app.kill("error during init", true);
6040            handleAppDiedLocked(app, false, true);
6041            return false;
6042        }
6043
6044        if (!didSomething) {
6045            updateOomAdjLocked();
6046        }
6047
6048        return true;
6049    }
6050
6051    @Override
6052    public final void attachApplication(IApplicationThread thread) {
6053        synchronized (this) {
6054            int callingPid = Binder.getCallingPid();
6055            final long origId = Binder.clearCallingIdentity();
6056            attachApplicationLocked(thread, callingPid);
6057            Binder.restoreCallingIdentity(origId);
6058        }
6059    }
6060
6061    @Override
6062    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6063        final long origId = Binder.clearCallingIdentity();
6064        synchronized (this) {
6065            ActivityStack stack = ActivityRecord.getStackLocked(token);
6066            if (stack != null) {
6067                ActivityRecord r =
6068                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6069                if (stopProfiling) {
6070                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6071                        try {
6072                            mProfileFd.close();
6073                        } catch (IOException e) {
6074                        }
6075                        clearProfilerLocked();
6076                    }
6077                }
6078            }
6079        }
6080        Binder.restoreCallingIdentity(origId);
6081    }
6082
6083    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6084        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6085                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6086    }
6087
6088    void enableScreenAfterBoot() {
6089        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6090                SystemClock.uptimeMillis());
6091        mWindowManager.enableScreenAfterBoot();
6092
6093        synchronized (this) {
6094            updateEventDispatchingLocked();
6095        }
6096    }
6097
6098    @Override
6099    public void showBootMessage(final CharSequence msg, final boolean always) {
6100        enforceNotIsolatedCaller("showBootMessage");
6101        mWindowManager.showBootMessage(msg, always);
6102    }
6103
6104    @Override
6105    public void keyguardWaitingForActivityDrawn() {
6106        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6107        final long token = Binder.clearCallingIdentity();
6108        try {
6109            synchronized (this) {
6110                if (DEBUG_LOCKSCREEN) logLockScreen("");
6111                mWindowManager.keyguardWaitingForActivityDrawn();
6112                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6113                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6114                    updateSleepIfNeededLocked();
6115                }
6116            }
6117        } finally {
6118            Binder.restoreCallingIdentity(token);
6119        }
6120    }
6121
6122    final void finishBooting() {
6123        synchronized (this) {
6124            if (!mBootAnimationComplete) {
6125                mCallFinishBooting = true;
6126                return;
6127            }
6128            mCallFinishBooting = false;
6129        }
6130
6131        ArraySet<String> completedIsas = new ArraySet<String>();
6132        for (String abi : Build.SUPPORTED_ABIS) {
6133            Process.establishZygoteConnectionForAbi(abi);
6134            final String instructionSet = VMRuntime.getInstructionSet(abi);
6135            if (!completedIsas.contains(instructionSet)) {
6136                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6137                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6138                }
6139                completedIsas.add(instructionSet);
6140            }
6141        }
6142
6143        IntentFilter pkgFilter = new IntentFilter();
6144        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6145        pkgFilter.addDataScheme("package");
6146        mContext.registerReceiver(new BroadcastReceiver() {
6147            @Override
6148            public void onReceive(Context context, Intent intent) {
6149                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6150                if (pkgs != null) {
6151                    for (String pkg : pkgs) {
6152                        synchronized (ActivityManagerService.this) {
6153                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6154                                    0, "finished booting")) {
6155                                setResultCode(Activity.RESULT_OK);
6156                                return;
6157                            }
6158                        }
6159                    }
6160                }
6161            }
6162        }, pkgFilter);
6163
6164        // Let system services know.
6165        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6166
6167        synchronized (this) {
6168            // Ensure that any processes we had put on hold are now started
6169            // up.
6170            final int NP = mProcessesOnHold.size();
6171            if (NP > 0) {
6172                ArrayList<ProcessRecord> procs =
6173                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6174                for (int ip=0; ip<NP; ip++) {
6175                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6176                            + procs.get(ip));
6177                    startProcessLocked(procs.get(ip), "on-hold", null);
6178                }
6179            }
6180
6181            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6182                // Start looking for apps that are abusing wake locks.
6183                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6184                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6185                // Tell anyone interested that we are done booting!
6186                SystemProperties.set("sys.boot_completed", "1");
6187
6188                // And trigger dev.bootcomplete if we are not showing encryption progress
6189                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6190                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6191                    SystemProperties.set("dev.bootcomplete", "1");
6192                }
6193                for (int i=0; i<mStartedUsers.size(); i++) {
6194                    UserStartedState uss = mStartedUsers.valueAt(i);
6195                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6196                        uss.mState = UserStartedState.STATE_RUNNING;
6197                        final int userId = mStartedUsers.keyAt(i);
6198                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6199                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6200                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6201                        broadcastIntentLocked(null, null, intent, null,
6202                                new IIntentReceiver.Stub() {
6203                                    @Override
6204                                    public void performReceive(Intent intent, int resultCode,
6205                                            String data, Bundle extras, boolean ordered,
6206                                            boolean sticky, int sendingUser) {
6207                                        synchronized (ActivityManagerService.this) {
6208                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6209                                                    true, false);
6210                                        }
6211                                    }
6212                                },
6213                                0, null, null,
6214                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6215                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6216                                userId);
6217                    }
6218                }
6219                scheduleStartProfilesLocked();
6220            }
6221        }
6222    }
6223
6224    @Override
6225    public void bootAnimationComplete() {
6226        final boolean callFinishBooting;
6227        synchronized (this) {
6228            callFinishBooting = mCallFinishBooting;
6229            mBootAnimationComplete = true;
6230        }
6231        if (callFinishBooting) {
6232            finishBooting();
6233        }
6234    }
6235
6236    @Override
6237    public void systemBackupRestored() {
6238        synchronized (this) {
6239            if (mSystemReady) {
6240                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6241            } else {
6242                Slog.w(TAG, "System backup restored before system is ready");
6243            }
6244        }
6245    }
6246
6247    final void ensureBootCompleted() {
6248        boolean booting;
6249        boolean enableScreen;
6250        synchronized (this) {
6251            booting = mBooting;
6252            mBooting = false;
6253            enableScreen = !mBooted;
6254            mBooted = true;
6255        }
6256
6257        if (booting) {
6258            finishBooting();
6259        }
6260
6261        if (enableScreen) {
6262            enableScreenAfterBoot();
6263        }
6264    }
6265
6266    @Override
6267    public final void activityResumed(IBinder token) {
6268        final long origId = Binder.clearCallingIdentity();
6269        synchronized(this) {
6270            ActivityStack stack = ActivityRecord.getStackLocked(token);
6271            if (stack != null) {
6272                ActivityRecord.activityResumedLocked(token);
6273            }
6274        }
6275        Binder.restoreCallingIdentity(origId);
6276    }
6277
6278    @Override
6279    public final void activityPaused(IBinder token) {
6280        final long origId = Binder.clearCallingIdentity();
6281        synchronized(this) {
6282            ActivityStack stack = ActivityRecord.getStackLocked(token);
6283            if (stack != null) {
6284                stack.activityPausedLocked(token, false);
6285            }
6286        }
6287        Binder.restoreCallingIdentity(origId);
6288    }
6289
6290    @Override
6291    public final void activityStopped(IBinder token, Bundle icicle,
6292            PersistableBundle persistentState, CharSequence description) {
6293        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6294
6295        // Refuse possible leaked file descriptors
6296        if (icicle != null && icicle.hasFileDescriptors()) {
6297            throw new IllegalArgumentException("File descriptors passed in Bundle");
6298        }
6299
6300        final long origId = Binder.clearCallingIdentity();
6301
6302        synchronized (this) {
6303            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6304            if (r != null) {
6305                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6306            }
6307        }
6308
6309        trimApplications();
6310
6311        Binder.restoreCallingIdentity(origId);
6312    }
6313
6314    @Override
6315    public final void activityDestroyed(IBinder token) {
6316        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6317        synchronized (this) {
6318            ActivityStack stack = ActivityRecord.getStackLocked(token);
6319            if (stack != null) {
6320                stack.activityDestroyedLocked(token);
6321            }
6322        }
6323    }
6324
6325    @Override
6326    public final void backgroundResourcesReleased(IBinder token) {
6327        final long origId = Binder.clearCallingIdentity();
6328        try {
6329            synchronized (this) {
6330                ActivityStack stack = ActivityRecord.getStackLocked(token);
6331                if (stack != null) {
6332                    stack.backgroundResourcesReleased();
6333                }
6334            }
6335        } finally {
6336            Binder.restoreCallingIdentity(origId);
6337        }
6338    }
6339
6340    @Override
6341    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6342        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6343    }
6344
6345    @Override
6346    public final void notifyEnterAnimationComplete(IBinder token) {
6347        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6348    }
6349
6350    @Override
6351    public String getCallingPackage(IBinder token) {
6352        synchronized (this) {
6353            ActivityRecord r = getCallingRecordLocked(token);
6354            return r != null ? r.info.packageName : null;
6355        }
6356    }
6357
6358    @Override
6359    public ComponentName getCallingActivity(IBinder token) {
6360        synchronized (this) {
6361            ActivityRecord r = getCallingRecordLocked(token);
6362            return r != null ? r.intent.getComponent() : null;
6363        }
6364    }
6365
6366    private ActivityRecord getCallingRecordLocked(IBinder token) {
6367        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6368        if (r == null) {
6369            return null;
6370        }
6371        return r.resultTo;
6372    }
6373
6374    @Override
6375    public ComponentName getActivityClassForToken(IBinder token) {
6376        synchronized(this) {
6377            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6378            if (r == null) {
6379                return null;
6380            }
6381            return r.intent.getComponent();
6382        }
6383    }
6384
6385    @Override
6386    public String getPackageForToken(IBinder token) {
6387        synchronized(this) {
6388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6389            if (r == null) {
6390                return null;
6391            }
6392            return r.packageName;
6393        }
6394    }
6395
6396    @Override
6397    public IIntentSender getIntentSender(int type,
6398            String packageName, IBinder token, String resultWho,
6399            int requestCode, Intent[] intents, String[] resolvedTypes,
6400            int flags, Bundle options, int userId) {
6401        enforceNotIsolatedCaller("getIntentSender");
6402        // Refuse possible leaked file descriptors
6403        if (intents != null) {
6404            if (intents.length < 1) {
6405                throw new IllegalArgumentException("Intents array length must be >= 1");
6406            }
6407            for (int i=0; i<intents.length; i++) {
6408                Intent intent = intents[i];
6409                if (intent != null) {
6410                    if (intent.hasFileDescriptors()) {
6411                        throw new IllegalArgumentException("File descriptors passed in Intent");
6412                    }
6413                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6414                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6415                        throw new IllegalArgumentException(
6416                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6417                    }
6418                    intents[i] = new Intent(intent);
6419                }
6420            }
6421            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6422                throw new IllegalArgumentException(
6423                        "Intent array length does not match resolvedTypes length");
6424            }
6425        }
6426        if (options != null) {
6427            if (options.hasFileDescriptors()) {
6428                throw new IllegalArgumentException("File descriptors passed in options");
6429            }
6430        }
6431
6432        synchronized(this) {
6433            int callingUid = Binder.getCallingUid();
6434            int origUserId = userId;
6435            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6436                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6437                    ALLOW_NON_FULL, "getIntentSender", null);
6438            if (origUserId == UserHandle.USER_CURRENT) {
6439                // We don't want to evaluate this until the pending intent is
6440                // actually executed.  However, we do want to always do the
6441                // security checking for it above.
6442                userId = UserHandle.USER_CURRENT;
6443            }
6444            try {
6445                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6446                    int uid = AppGlobals.getPackageManager()
6447                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6448                    if (!UserHandle.isSameApp(callingUid, uid)) {
6449                        String msg = "Permission Denial: getIntentSender() from pid="
6450                            + Binder.getCallingPid()
6451                            + ", uid=" + Binder.getCallingUid()
6452                            + ", (need uid=" + uid + ")"
6453                            + " is not allowed to send as package " + packageName;
6454                        Slog.w(TAG, msg);
6455                        throw new SecurityException(msg);
6456                    }
6457                }
6458
6459                return getIntentSenderLocked(type, packageName, callingUid, userId,
6460                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6461
6462            } catch (RemoteException e) {
6463                throw new SecurityException(e);
6464            }
6465        }
6466    }
6467
6468    IIntentSender getIntentSenderLocked(int type, String packageName,
6469            int callingUid, int userId, IBinder token, String resultWho,
6470            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6471            Bundle options) {
6472        if (DEBUG_MU)
6473            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6474        ActivityRecord activity = null;
6475        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6476            activity = ActivityRecord.isInStackLocked(token);
6477            if (activity == null) {
6478                return null;
6479            }
6480            if (activity.finishing) {
6481                return null;
6482            }
6483        }
6484
6485        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6486        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6487        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6488        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6489                |PendingIntent.FLAG_UPDATE_CURRENT);
6490
6491        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6492                type, packageName, activity, resultWho,
6493                requestCode, intents, resolvedTypes, flags, options, userId);
6494        WeakReference<PendingIntentRecord> ref;
6495        ref = mIntentSenderRecords.get(key);
6496        PendingIntentRecord rec = ref != null ? ref.get() : null;
6497        if (rec != null) {
6498            if (!cancelCurrent) {
6499                if (updateCurrent) {
6500                    if (rec.key.requestIntent != null) {
6501                        rec.key.requestIntent.replaceExtras(intents != null ?
6502                                intents[intents.length - 1] : null);
6503                    }
6504                    if (intents != null) {
6505                        intents[intents.length-1] = rec.key.requestIntent;
6506                        rec.key.allIntents = intents;
6507                        rec.key.allResolvedTypes = resolvedTypes;
6508                    } else {
6509                        rec.key.allIntents = null;
6510                        rec.key.allResolvedTypes = null;
6511                    }
6512                }
6513                return rec;
6514            }
6515            rec.canceled = true;
6516            mIntentSenderRecords.remove(key);
6517        }
6518        if (noCreate) {
6519            return rec;
6520        }
6521        rec = new PendingIntentRecord(this, key, callingUid);
6522        mIntentSenderRecords.put(key, rec.ref);
6523        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6524            if (activity.pendingResults == null) {
6525                activity.pendingResults
6526                        = new HashSet<WeakReference<PendingIntentRecord>>();
6527            }
6528            activity.pendingResults.add(rec.ref);
6529        }
6530        return rec;
6531    }
6532
6533    @Override
6534    public void cancelIntentSender(IIntentSender sender) {
6535        if (!(sender instanceof PendingIntentRecord)) {
6536            return;
6537        }
6538        synchronized(this) {
6539            PendingIntentRecord rec = (PendingIntentRecord)sender;
6540            try {
6541                int uid = AppGlobals.getPackageManager()
6542                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6543                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6544                    String msg = "Permission Denial: cancelIntentSender() from pid="
6545                        + Binder.getCallingPid()
6546                        + ", uid=" + Binder.getCallingUid()
6547                        + " is not allowed to cancel packges "
6548                        + rec.key.packageName;
6549                    Slog.w(TAG, msg);
6550                    throw new SecurityException(msg);
6551                }
6552            } catch (RemoteException e) {
6553                throw new SecurityException(e);
6554            }
6555            cancelIntentSenderLocked(rec, true);
6556        }
6557    }
6558
6559    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6560        rec.canceled = true;
6561        mIntentSenderRecords.remove(rec.key);
6562        if (cleanActivity && rec.key.activity != null) {
6563            rec.key.activity.pendingResults.remove(rec.ref);
6564        }
6565    }
6566
6567    @Override
6568    public String getPackageForIntentSender(IIntentSender pendingResult) {
6569        if (!(pendingResult instanceof PendingIntentRecord)) {
6570            return null;
6571        }
6572        try {
6573            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6574            return res.key.packageName;
6575        } catch (ClassCastException e) {
6576        }
6577        return null;
6578    }
6579
6580    @Override
6581    public int getUidForIntentSender(IIntentSender sender) {
6582        if (sender instanceof PendingIntentRecord) {
6583            try {
6584                PendingIntentRecord res = (PendingIntentRecord)sender;
6585                return res.uid;
6586            } catch (ClassCastException e) {
6587            }
6588        }
6589        return -1;
6590    }
6591
6592    @Override
6593    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6594        if (!(pendingResult instanceof PendingIntentRecord)) {
6595            return false;
6596        }
6597        try {
6598            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6599            if (res.key.allIntents == null) {
6600                return false;
6601            }
6602            for (int i=0; i<res.key.allIntents.length; i++) {
6603                Intent intent = res.key.allIntents[i];
6604                if (intent.getPackage() != null && intent.getComponent() != null) {
6605                    return false;
6606                }
6607            }
6608            return true;
6609        } catch (ClassCastException e) {
6610        }
6611        return false;
6612    }
6613
6614    @Override
6615    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6616        if (!(pendingResult instanceof PendingIntentRecord)) {
6617            return false;
6618        }
6619        try {
6620            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6621            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6622                return true;
6623            }
6624            return false;
6625        } catch (ClassCastException e) {
6626        }
6627        return false;
6628    }
6629
6630    @Override
6631    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6632        if (!(pendingResult instanceof PendingIntentRecord)) {
6633            return null;
6634        }
6635        try {
6636            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6637            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6638        } catch (ClassCastException e) {
6639        }
6640        return null;
6641    }
6642
6643    @Override
6644    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6645        if (!(pendingResult instanceof PendingIntentRecord)) {
6646            return null;
6647        }
6648        try {
6649            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6650            Intent intent = res.key.requestIntent;
6651            if (intent != null) {
6652                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6653                        || res.lastTagPrefix.equals(prefix))) {
6654                    return res.lastTag;
6655                }
6656                res.lastTagPrefix = prefix;
6657                StringBuilder sb = new StringBuilder(128);
6658                if (prefix != null) {
6659                    sb.append(prefix);
6660                }
6661                if (intent.getAction() != null) {
6662                    sb.append(intent.getAction());
6663                } else if (intent.getComponent() != null) {
6664                    intent.getComponent().appendShortString(sb);
6665                } else {
6666                    sb.append("?");
6667                }
6668                return res.lastTag = sb.toString();
6669            }
6670        } catch (ClassCastException e) {
6671        }
6672        return null;
6673    }
6674
6675    @Override
6676    public void setProcessLimit(int max) {
6677        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6678                "setProcessLimit()");
6679        synchronized (this) {
6680            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6681            mProcessLimitOverride = max;
6682        }
6683        trimApplications();
6684    }
6685
6686    @Override
6687    public int getProcessLimit() {
6688        synchronized (this) {
6689            return mProcessLimitOverride;
6690        }
6691    }
6692
6693    void foregroundTokenDied(ForegroundToken token) {
6694        synchronized (ActivityManagerService.this) {
6695            synchronized (mPidsSelfLocked) {
6696                ForegroundToken cur
6697                    = mForegroundProcesses.get(token.pid);
6698                if (cur != token) {
6699                    return;
6700                }
6701                mForegroundProcesses.remove(token.pid);
6702                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6703                if (pr == null) {
6704                    return;
6705                }
6706                pr.forcingToForeground = null;
6707                updateProcessForegroundLocked(pr, false, false);
6708            }
6709            updateOomAdjLocked();
6710        }
6711    }
6712
6713    @Override
6714    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6715        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6716                "setProcessForeground()");
6717        synchronized(this) {
6718            boolean changed = false;
6719
6720            synchronized (mPidsSelfLocked) {
6721                ProcessRecord pr = mPidsSelfLocked.get(pid);
6722                if (pr == null && isForeground) {
6723                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6724                    return;
6725                }
6726                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6727                if (oldToken != null) {
6728                    oldToken.token.unlinkToDeath(oldToken, 0);
6729                    mForegroundProcesses.remove(pid);
6730                    if (pr != null) {
6731                        pr.forcingToForeground = null;
6732                    }
6733                    changed = true;
6734                }
6735                if (isForeground && token != null) {
6736                    ForegroundToken newToken = new ForegroundToken() {
6737                        @Override
6738                        public void binderDied() {
6739                            foregroundTokenDied(this);
6740                        }
6741                    };
6742                    newToken.pid = pid;
6743                    newToken.token = token;
6744                    try {
6745                        token.linkToDeath(newToken, 0);
6746                        mForegroundProcesses.put(pid, newToken);
6747                        pr.forcingToForeground = token;
6748                        changed = true;
6749                    } catch (RemoteException e) {
6750                        // If the process died while doing this, we will later
6751                        // do the cleanup with the process death link.
6752                    }
6753                }
6754            }
6755
6756            if (changed) {
6757                updateOomAdjLocked();
6758            }
6759        }
6760    }
6761
6762    // =========================================================
6763    // PERMISSIONS
6764    // =========================================================
6765
6766    static class PermissionController extends IPermissionController.Stub {
6767        ActivityManagerService mActivityManagerService;
6768        PermissionController(ActivityManagerService activityManagerService) {
6769            mActivityManagerService = activityManagerService;
6770        }
6771
6772        @Override
6773        public boolean checkPermission(String permission, int pid, int uid) {
6774            return mActivityManagerService.checkPermission(permission, pid,
6775                    uid) == PackageManager.PERMISSION_GRANTED;
6776        }
6777    }
6778
6779    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6780        @Override
6781        public int checkComponentPermission(String permission, int pid, int uid,
6782                int owningUid, boolean exported) {
6783            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6784                    owningUid, exported);
6785        }
6786
6787        @Override
6788        public Object getAMSLock() {
6789            return ActivityManagerService.this;
6790        }
6791    }
6792
6793    /**
6794     * This can be called with or without the global lock held.
6795     */
6796    int checkComponentPermission(String permission, int pid, int uid,
6797            int owningUid, boolean exported) {
6798        if (pid == MY_PID) {
6799            return PackageManager.PERMISSION_GRANTED;
6800        }
6801        return ActivityManager.checkComponentPermission(permission, uid,
6802                owningUid, exported);
6803    }
6804
6805    /**
6806     * As the only public entry point for permissions checking, this method
6807     * can enforce the semantic that requesting a check on a null global
6808     * permission is automatically denied.  (Internally a null permission
6809     * string is used when calling {@link #checkComponentPermission} in cases
6810     * when only uid-based security is needed.)
6811     *
6812     * This can be called with or without the global lock held.
6813     */
6814    @Override
6815    public int checkPermission(String permission, int pid, int uid) {
6816        if (permission == null) {
6817            return PackageManager.PERMISSION_DENIED;
6818        }
6819        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6820    }
6821
6822    @Override
6823    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6824        if (permission == null) {
6825            return PackageManager.PERMISSION_DENIED;
6826        }
6827
6828        // We might be performing an operation on behalf of an indirect binder
6829        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6830        // client identity accordingly before proceeding.
6831        Identity tlsIdentity = sCallerIdentity.get();
6832        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6833            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6834                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6835            uid = tlsIdentity.uid;
6836            pid = tlsIdentity.pid;
6837        }
6838
6839        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6840    }
6841
6842    /**
6843     * Binder IPC calls go through the public entry point.
6844     * This can be called with or without the global lock held.
6845     */
6846    int checkCallingPermission(String permission) {
6847        return checkPermission(permission,
6848                Binder.getCallingPid(),
6849                UserHandle.getAppId(Binder.getCallingUid()));
6850    }
6851
6852    /**
6853     * This can be called with or without the global lock held.
6854     */
6855    void enforceCallingPermission(String permission, String func) {
6856        if (checkCallingPermission(permission)
6857                == PackageManager.PERMISSION_GRANTED) {
6858            return;
6859        }
6860
6861        String msg = "Permission Denial: " + func + " from pid="
6862                + Binder.getCallingPid()
6863                + ", uid=" + Binder.getCallingUid()
6864                + " requires " + permission;
6865        Slog.w(TAG, msg);
6866        throw new SecurityException(msg);
6867    }
6868
6869    /**
6870     * Determine if UID is holding permissions required to access {@link Uri} in
6871     * the given {@link ProviderInfo}. Final permission checking is always done
6872     * in {@link ContentProvider}.
6873     */
6874    private final boolean checkHoldingPermissionsLocked(
6875            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6876        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6877                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6878        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6879            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6880                    != PERMISSION_GRANTED) {
6881                return false;
6882            }
6883        }
6884        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6885    }
6886
6887    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6888            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6889        if (pi.applicationInfo.uid == uid) {
6890            return true;
6891        } else if (!pi.exported) {
6892            return false;
6893        }
6894
6895        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6896        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6897        try {
6898            // check if target holds top-level <provider> permissions
6899            if (!readMet && pi.readPermission != null && considerUidPermissions
6900                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6901                readMet = true;
6902            }
6903            if (!writeMet && pi.writePermission != null && considerUidPermissions
6904                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6905                writeMet = true;
6906            }
6907
6908            // track if unprotected read/write is allowed; any denied
6909            // <path-permission> below removes this ability
6910            boolean allowDefaultRead = pi.readPermission == null;
6911            boolean allowDefaultWrite = pi.writePermission == null;
6912
6913            // check if target holds any <path-permission> that match uri
6914            final PathPermission[] pps = pi.pathPermissions;
6915            if (pps != null) {
6916                final String path = grantUri.uri.getPath();
6917                int i = pps.length;
6918                while (i > 0 && (!readMet || !writeMet)) {
6919                    i--;
6920                    PathPermission pp = pps[i];
6921                    if (pp.match(path)) {
6922                        if (!readMet) {
6923                            final String pprperm = pp.getReadPermission();
6924                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6925                                    + pprperm + " for " + pp.getPath()
6926                                    + ": match=" + pp.match(path)
6927                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6928                            if (pprperm != null) {
6929                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6930                                        == PERMISSION_GRANTED) {
6931                                    readMet = true;
6932                                } else {
6933                                    allowDefaultRead = false;
6934                                }
6935                            }
6936                        }
6937                        if (!writeMet) {
6938                            final String ppwperm = pp.getWritePermission();
6939                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6940                                    + ppwperm + " for " + pp.getPath()
6941                                    + ": match=" + pp.match(path)
6942                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6943                            if (ppwperm != null) {
6944                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6945                                        == PERMISSION_GRANTED) {
6946                                    writeMet = true;
6947                                } else {
6948                                    allowDefaultWrite = false;
6949                                }
6950                            }
6951                        }
6952                    }
6953                }
6954            }
6955
6956            // grant unprotected <provider> read/write, if not blocked by
6957            // <path-permission> above
6958            if (allowDefaultRead) readMet = true;
6959            if (allowDefaultWrite) writeMet = true;
6960
6961        } catch (RemoteException e) {
6962            return false;
6963        }
6964
6965        return readMet && writeMet;
6966    }
6967
6968    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6969        ProviderInfo pi = null;
6970        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6971        if (cpr != null) {
6972            pi = cpr.info;
6973        } else {
6974            try {
6975                pi = AppGlobals.getPackageManager().resolveContentProvider(
6976                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6977            } catch (RemoteException ex) {
6978            }
6979        }
6980        return pi;
6981    }
6982
6983    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6984        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6985        if (targetUris != null) {
6986            return targetUris.get(grantUri);
6987        }
6988        return null;
6989    }
6990
6991    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6992            String targetPkg, int targetUid, GrantUri grantUri) {
6993        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6994        if (targetUris == null) {
6995            targetUris = Maps.newArrayMap();
6996            mGrantedUriPermissions.put(targetUid, targetUris);
6997        }
6998
6999        UriPermission perm = targetUris.get(grantUri);
7000        if (perm == null) {
7001            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7002            targetUris.put(grantUri, perm);
7003        }
7004
7005        return perm;
7006    }
7007
7008    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7009            final int modeFlags) {
7010        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7011        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7012                : UriPermission.STRENGTH_OWNED;
7013
7014        // Root gets to do everything.
7015        if (uid == 0) {
7016            return true;
7017        }
7018
7019        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7020        if (perms == null) return false;
7021
7022        // First look for exact match
7023        final UriPermission exactPerm = perms.get(grantUri);
7024        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7025            return true;
7026        }
7027
7028        // No exact match, look for prefixes
7029        final int N = perms.size();
7030        for (int i = 0; i < N; i++) {
7031            final UriPermission perm = perms.valueAt(i);
7032            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7033                    && perm.getStrength(modeFlags) >= minStrength) {
7034                return true;
7035            }
7036        }
7037
7038        return false;
7039    }
7040
7041    /**
7042     * @param uri This uri must NOT contain an embedded userId.
7043     * @param userId The userId in which the uri is to be resolved.
7044     */
7045    @Override
7046    public int checkUriPermission(Uri uri, int pid, int uid,
7047            final int modeFlags, int userId, IBinder callerToken) {
7048        enforceNotIsolatedCaller("checkUriPermission");
7049
7050        // Another redirected-binder-call permissions check as in
7051        // {@link checkPermissionWithToken}.
7052        Identity tlsIdentity = sCallerIdentity.get();
7053        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7054            uid = tlsIdentity.uid;
7055            pid = tlsIdentity.pid;
7056        }
7057
7058        // Our own process gets to do everything.
7059        if (pid == MY_PID) {
7060            return PackageManager.PERMISSION_GRANTED;
7061        }
7062        synchronized (this) {
7063            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7064                    ? PackageManager.PERMISSION_GRANTED
7065                    : PackageManager.PERMISSION_DENIED;
7066        }
7067    }
7068
7069    /**
7070     * Check if the targetPkg can be granted permission to access uri by
7071     * the callingUid using the given modeFlags.  Throws a security exception
7072     * if callingUid is not allowed to do this.  Returns the uid of the target
7073     * if the URI permission grant should be performed; returns -1 if it is not
7074     * needed (for example targetPkg already has permission to access the URI).
7075     * If you already know the uid of the target, you can supply it in
7076     * lastTargetUid else set that to -1.
7077     */
7078    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7079            final int modeFlags, int lastTargetUid) {
7080        if (!Intent.isAccessUriMode(modeFlags)) {
7081            return -1;
7082        }
7083
7084        if (targetPkg != null) {
7085            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7086                    "Checking grant " + targetPkg + " permission to " + grantUri);
7087        }
7088
7089        final IPackageManager pm = AppGlobals.getPackageManager();
7090
7091        // If this is not a content: uri, we can't do anything with it.
7092        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7093            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7094                    "Can't grant URI permission for non-content URI: " + grantUri);
7095            return -1;
7096        }
7097
7098        final String authority = grantUri.uri.getAuthority();
7099        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7100        if (pi == null) {
7101            Slog.w(TAG, "No content provider found for permission check: " +
7102                    grantUri.uri.toSafeString());
7103            return -1;
7104        }
7105
7106        int targetUid = lastTargetUid;
7107        if (targetUid < 0 && targetPkg != null) {
7108            try {
7109                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7110                if (targetUid < 0) {
7111                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7112                            "Can't grant URI permission no uid for: " + targetPkg);
7113                    return -1;
7114                }
7115            } catch (RemoteException ex) {
7116                return -1;
7117            }
7118        }
7119
7120        if (targetUid >= 0) {
7121            // First...  does the target actually need this permission?
7122            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7123                // No need to grant the target this permission.
7124                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7125                        "Target " + targetPkg + " already has full permission to " + grantUri);
7126                return -1;
7127            }
7128        } else {
7129            // First...  there is no target package, so can anyone access it?
7130            boolean allowed = pi.exported;
7131            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7132                if (pi.readPermission != null) {
7133                    allowed = false;
7134                }
7135            }
7136            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7137                if (pi.writePermission != null) {
7138                    allowed = false;
7139                }
7140            }
7141            if (allowed) {
7142                return -1;
7143            }
7144        }
7145
7146        /* There is a special cross user grant if:
7147         * - The target is on another user.
7148         * - Apps on the current user can access the uri without any uid permissions.
7149         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7150         * grant uri permissions.
7151         */
7152        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7153                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7154                modeFlags, false /*without considering the uid permissions*/);
7155
7156        // Second...  is the provider allowing granting of URI permissions?
7157        if (!specialCrossUserGrant) {
7158            if (!pi.grantUriPermissions) {
7159                throw new SecurityException("Provider " + pi.packageName
7160                        + "/" + pi.name
7161                        + " does not allow granting of Uri permissions (uri "
7162                        + grantUri + ")");
7163            }
7164            if (pi.uriPermissionPatterns != null) {
7165                final int N = pi.uriPermissionPatterns.length;
7166                boolean allowed = false;
7167                for (int i=0; i<N; i++) {
7168                    if (pi.uriPermissionPatterns[i] != null
7169                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7170                        allowed = true;
7171                        break;
7172                    }
7173                }
7174                if (!allowed) {
7175                    throw new SecurityException("Provider " + pi.packageName
7176                            + "/" + pi.name
7177                            + " does not allow granting of permission to path of Uri "
7178                            + grantUri);
7179                }
7180            }
7181        }
7182
7183        // Third...  does the caller itself have permission to access
7184        // this uri?
7185        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7186            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7187                // Require they hold a strong enough Uri permission
7188                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7189                    throw new SecurityException("Uid " + callingUid
7190                            + " does not have permission to uri " + grantUri);
7191                }
7192            }
7193        }
7194        return targetUid;
7195    }
7196
7197    /**
7198     * @param uri This uri must NOT contain an embedded userId.
7199     * @param userId The userId in which the uri is to be resolved.
7200     */
7201    @Override
7202    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7203            final int modeFlags, int userId) {
7204        enforceNotIsolatedCaller("checkGrantUriPermission");
7205        synchronized(this) {
7206            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7207                    new GrantUri(userId, uri, false), modeFlags, -1);
7208        }
7209    }
7210
7211    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7212            final int modeFlags, UriPermissionOwner owner) {
7213        if (!Intent.isAccessUriMode(modeFlags)) {
7214            return;
7215        }
7216
7217        // So here we are: the caller has the assumed permission
7218        // to the uri, and the target doesn't.  Let's now give this to
7219        // the target.
7220
7221        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7222                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7223
7224        final String authority = grantUri.uri.getAuthority();
7225        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7226        if (pi == null) {
7227            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7228            return;
7229        }
7230
7231        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7232            grantUri.prefix = true;
7233        }
7234        final UriPermission perm = findOrCreateUriPermissionLocked(
7235                pi.packageName, targetPkg, targetUid, grantUri);
7236        perm.grantModes(modeFlags, owner);
7237    }
7238
7239    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7240            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7241        if (targetPkg == null) {
7242            throw new NullPointerException("targetPkg");
7243        }
7244        int targetUid;
7245        final IPackageManager pm = AppGlobals.getPackageManager();
7246        try {
7247            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7248        } catch (RemoteException ex) {
7249            return;
7250        }
7251
7252        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7253                targetUid);
7254        if (targetUid < 0) {
7255            return;
7256        }
7257
7258        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7259                owner);
7260    }
7261
7262    static class NeededUriGrants extends ArrayList<GrantUri> {
7263        final String targetPkg;
7264        final int targetUid;
7265        final int flags;
7266
7267        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7268            this.targetPkg = targetPkg;
7269            this.targetUid = targetUid;
7270            this.flags = flags;
7271        }
7272    }
7273
7274    /**
7275     * Like checkGrantUriPermissionLocked, but takes an Intent.
7276     */
7277    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7278            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7279        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7280                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7281                + " clip=" + (intent != null ? intent.getClipData() : null)
7282                + " from " + intent + "; flags=0x"
7283                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7284
7285        if (targetPkg == null) {
7286            throw new NullPointerException("targetPkg");
7287        }
7288
7289        if (intent == null) {
7290            return null;
7291        }
7292        Uri data = intent.getData();
7293        ClipData clip = intent.getClipData();
7294        if (data == null && clip == null) {
7295            return null;
7296        }
7297        // Default userId for uris in the intent (if they don't specify it themselves)
7298        int contentUserHint = intent.getContentUserHint();
7299        if (contentUserHint == UserHandle.USER_CURRENT) {
7300            contentUserHint = UserHandle.getUserId(callingUid);
7301        }
7302        final IPackageManager pm = AppGlobals.getPackageManager();
7303        int targetUid;
7304        if (needed != null) {
7305            targetUid = needed.targetUid;
7306        } else {
7307            try {
7308                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7309            } catch (RemoteException ex) {
7310                return null;
7311            }
7312            if (targetUid < 0) {
7313                if (DEBUG_URI_PERMISSION) {
7314                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7315                            + " on user " + targetUserId);
7316                }
7317                return null;
7318            }
7319        }
7320        if (data != null) {
7321            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7322            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7323                    targetUid);
7324            if (targetUid > 0) {
7325                if (needed == null) {
7326                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7327                }
7328                needed.add(grantUri);
7329            }
7330        }
7331        if (clip != null) {
7332            for (int i=0; i<clip.getItemCount(); i++) {
7333                Uri uri = clip.getItemAt(i).getUri();
7334                if (uri != null) {
7335                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7336                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7337                            targetUid);
7338                    if (targetUid > 0) {
7339                        if (needed == null) {
7340                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7341                        }
7342                        needed.add(grantUri);
7343                    }
7344                } else {
7345                    Intent clipIntent = clip.getItemAt(i).getIntent();
7346                    if (clipIntent != null) {
7347                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7348                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7349                        if (newNeeded != null) {
7350                            needed = newNeeded;
7351                        }
7352                    }
7353                }
7354            }
7355        }
7356
7357        return needed;
7358    }
7359
7360    /**
7361     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7362     */
7363    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7364            UriPermissionOwner owner) {
7365        if (needed != null) {
7366            for (int i=0; i<needed.size(); i++) {
7367                GrantUri grantUri = needed.get(i);
7368                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7369                        grantUri, needed.flags, owner);
7370            }
7371        }
7372    }
7373
7374    void grantUriPermissionFromIntentLocked(int callingUid,
7375            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7376        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7377                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7378        if (needed == null) {
7379            return;
7380        }
7381
7382        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7383    }
7384
7385    /**
7386     * @param uri This uri must NOT contain an embedded userId.
7387     * @param userId The userId in which the uri is to be resolved.
7388     */
7389    @Override
7390    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7391            final int modeFlags, int userId) {
7392        enforceNotIsolatedCaller("grantUriPermission");
7393        GrantUri grantUri = new GrantUri(userId, uri, false);
7394        synchronized(this) {
7395            final ProcessRecord r = getRecordForAppLocked(caller);
7396            if (r == null) {
7397                throw new SecurityException("Unable to find app for caller "
7398                        + caller
7399                        + " when granting permission to uri " + grantUri);
7400            }
7401            if (targetPkg == null) {
7402                throw new IllegalArgumentException("null target");
7403            }
7404            if (grantUri == null) {
7405                throw new IllegalArgumentException("null uri");
7406            }
7407
7408            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7409                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7410                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7411                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7412
7413            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7414                    UserHandle.getUserId(r.uid));
7415        }
7416    }
7417
7418    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7419        if (perm.modeFlags == 0) {
7420            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7421                    perm.targetUid);
7422            if (perms != null) {
7423                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7424                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7425
7426                perms.remove(perm.uri);
7427                if (perms.isEmpty()) {
7428                    mGrantedUriPermissions.remove(perm.targetUid);
7429                }
7430            }
7431        }
7432    }
7433
7434    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7435        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7436
7437        final IPackageManager pm = AppGlobals.getPackageManager();
7438        final String authority = grantUri.uri.getAuthority();
7439        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7440        if (pi == null) {
7441            Slog.w(TAG, "No content provider found for permission revoke: "
7442                    + grantUri.toSafeString());
7443            return;
7444        }
7445
7446        // Does the caller have this permission on the URI?
7447        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7448            // If they don't have direct access to the URI, then revoke any
7449            // ownerless URI permissions that have been granted to them.
7450            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7451            if (perms != null) {
7452                boolean persistChanged = false;
7453                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7454                    final UriPermission perm = it.next();
7455                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7456                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7457                        if (DEBUG_URI_PERMISSION)
7458                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7459                                    " permission to " + perm.uri);
7460                        persistChanged |= perm.revokeModes(
7461                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7462                        if (perm.modeFlags == 0) {
7463                            it.remove();
7464                        }
7465                    }
7466                }
7467                if (perms.isEmpty()) {
7468                    mGrantedUriPermissions.remove(callingUid);
7469                }
7470                if (persistChanged) {
7471                    schedulePersistUriGrants();
7472                }
7473            }
7474            return;
7475        }
7476
7477        boolean persistChanged = false;
7478
7479        // Go through all of the permissions and remove any that match.
7480        int N = mGrantedUriPermissions.size();
7481        for (int i = 0; i < N; i++) {
7482            final int targetUid = mGrantedUriPermissions.keyAt(i);
7483            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7484
7485            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7486                final UriPermission perm = it.next();
7487                if (perm.uri.sourceUserId == grantUri.sourceUserId
7488                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7489                    if (DEBUG_URI_PERMISSION)
7490                        Slog.v(TAG,
7491                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7492                    persistChanged |= perm.revokeModes(
7493                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7494                    if (perm.modeFlags == 0) {
7495                        it.remove();
7496                    }
7497                }
7498            }
7499
7500            if (perms.isEmpty()) {
7501                mGrantedUriPermissions.remove(targetUid);
7502                N--;
7503                i--;
7504            }
7505        }
7506
7507        if (persistChanged) {
7508            schedulePersistUriGrants();
7509        }
7510    }
7511
7512    /**
7513     * @param uri This uri must NOT contain an embedded userId.
7514     * @param userId The userId in which the uri is to be resolved.
7515     */
7516    @Override
7517    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7518            int userId) {
7519        enforceNotIsolatedCaller("revokeUriPermission");
7520        synchronized(this) {
7521            final ProcessRecord r = getRecordForAppLocked(caller);
7522            if (r == null) {
7523                throw new SecurityException("Unable to find app for caller "
7524                        + caller
7525                        + " when revoking permission to uri " + uri);
7526            }
7527            if (uri == null) {
7528                Slog.w(TAG, "revokeUriPermission: null uri");
7529                return;
7530            }
7531
7532            if (!Intent.isAccessUriMode(modeFlags)) {
7533                return;
7534            }
7535
7536            final IPackageManager pm = AppGlobals.getPackageManager();
7537            final String authority = uri.getAuthority();
7538            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7539            if (pi == null) {
7540                Slog.w(TAG, "No content provider found for permission revoke: "
7541                        + uri.toSafeString());
7542                return;
7543            }
7544
7545            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7546        }
7547    }
7548
7549    /**
7550     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7551     * given package.
7552     *
7553     * @param packageName Package name to match, or {@code null} to apply to all
7554     *            packages.
7555     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7556     *            to all users.
7557     * @param persistable If persistable grants should be removed.
7558     */
7559    private void removeUriPermissionsForPackageLocked(
7560            String packageName, int userHandle, boolean persistable) {
7561        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7562            throw new IllegalArgumentException("Must narrow by either package or user");
7563        }
7564
7565        boolean persistChanged = false;
7566
7567        int N = mGrantedUriPermissions.size();
7568        for (int i = 0; i < N; i++) {
7569            final int targetUid = mGrantedUriPermissions.keyAt(i);
7570            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7571
7572            // Only inspect grants matching user
7573            if (userHandle == UserHandle.USER_ALL
7574                    || userHandle == UserHandle.getUserId(targetUid)) {
7575                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7576                    final UriPermission perm = it.next();
7577
7578                    // Only inspect grants matching package
7579                    if (packageName == null || perm.sourcePkg.equals(packageName)
7580                            || perm.targetPkg.equals(packageName)) {
7581                        persistChanged |= perm.revokeModes(persistable
7582                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7583
7584                        // Only remove when no modes remain; any persisted grants
7585                        // will keep this alive.
7586                        if (perm.modeFlags == 0) {
7587                            it.remove();
7588                        }
7589                    }
7590                }
7591
7592                if (perms.isEmpty()) {
7593                    mGrantedUriPermissions.remove(targetUid);
7594                    N--;
7595                    i--;
7596                }
7597            }
7598        }
7599
7600        if (persistChanged) {
7601            schedulePersistUriGrants();
7602        }
7603    }
7604
7605    @Override
7606    public IBinder newUriPermissionOwner(String name) {
7607        enforceNotIsolatedCaller("newUriPermissionOwner");
7608        synchronized(this) {
7609            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7610            return owner.getExternalTokenLocked();
7611        }
7612    }
7613
7614    /**
7615     * @param uri This uri must NOT contain an embedded userId.
7616     * @param sourceUserId The userId in which the uri is to be resolved.
7617     * @param targetUserId The userId of the app that receives the grant.
7618     */
7619    @Override
7620    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7621            final int modeFlags, int sourceUserId, int targetUserId) {
7622        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7623                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7624        synchronized(this) {
7625            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7626            if (owner == null) {
7627                throw new IllegalArgumentException("Unknown owner: " + token);
7628            }
7629            if (fromUid != Binder.getCallingUid()) {
7630                if (Binder.getCallingUid() != Process.myUid()) {
7631                    // Only system code can grant URI permissions on behalf
7632                    // of other users.
7633                    throw new SecurityException("nice try");
7634                }
7635            }
7636            if (targetPkg == null) {
7637                throw new IllegalArgumentException("null target");
7638            }
7639            if (uri == null) {
7640                throw new IllegalArgumentException("null uri");
7641            }
7642
7643            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7644                    modeFlags, owner, targetUserId);
7645        }
7646    }
7647
7648    /**
7649     * @param uri This uri must NOT contain an embedded userId.
7650     * @param userId The userId in which the uri is to be resolved.
7651     */
7652    @Override
7653    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7654        synchronized(this) {
7655            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7656            if (owner == null) {
7657                throw new IllegalArgumentException("Unknown owner: " + token);
7658            }
7659
7660            if (uri == null) {
7661                owner.removeUriPermissionsLocked(mode);
7662            } else {
7663                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7664            }
7665        }
7666    }
7667
7668    private void schedulePersistUriGrants() {
7669        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7670            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7671                    10 * DateUtils.SECOND_IN_MILLIS);
7672        }
7673    }
7674
7675    private void writeGrantedUriPermissions() {
7676        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7677
7678        // Snapshot permissions so we can persist without lock
7679        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7680        synchronized (this) {
7681            final int size = mGrantedUriPermissions.size();
7682            for (int i = 0; i < size; i++) {
7683                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7684                for (UriPermission perm : perms.values()) {
7685                    if (perm.persistedModeFlags != 0) {
7686                        persist.add(perm.snapshot());
7687                    }
7688                }
7689            }
7690        }
7691
7692        FileOutputStream fos = null;
7693        try {
7694            fos = mGrantFile.startWrite();
7695
7696            XmlSerializer out = new FastXmlSerializer();
7697            out.setOutput(fos, "utf-8");
7698            out.startDocument(null, true);
7699            out.startTag(null, TAG_URI_GRANTS);
7700            for (UriPermission.Snapshot perm : persist) {
7701                out.startTag(null, TAG_URI_GRANT);
7702                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7703                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7704                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7705                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7706                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7707                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7708                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7709                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7710                out.endTag(null, TAG_URI_GRANT);
7711            }
7712            out.endTag(null, TAG_URI_GRANTS);
7713            out.endDocument();
7714
7715            mGrantFile.finishWrite(fos);
7716        } catch (IOException e) {
7717            if (fos != null) {
7718                mGrantFile.failWrite(fos);
7719            }
7720        }
7721    }
7722
7723    private void readGrantedUriPermissionsLocked() {
7724        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7725
7726        final long now = System.currentTimeMillis();
7727
7728        FileInputStream fis = null;
7729        try {
7730            fis = mGrantFile.openRead();
7731            final XmlPullParser in = Xml.newPullParser();
7732            in.setInput(fis, null);
7733
7734            int type;
7735            while ((type = in.next()) != END_DOCUMENT) {
7736                final String tag = in.getName();
7737                if (type == START_TAG) {
7738                    if (TAG_URI_GRANT.equals(tag)) {
7739                        final int sourceUserId;
7740                        final int targetUserId;
7741                        final int userHandle = readIntAttribute(in,
7742                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7743                        if (userHandle != UserHandle.USER_NULL) {
7744                            // For backwards compatibility.
7745                            sourceUserId = userHandle;
7746                            targetUserId = userHandle;
7747                        } else {
7748                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7749                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7750                        }
7751                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7752                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7753                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7754                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7755                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7756                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7757
7758                        // Sanity check that provider still belongs to source package
7759                        final ProviderInfo pi = getProviderInfoLocked(
7760                                uri.getAuthority(), sourceUserId);
7761                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7762                            int targetUid = -1;
7763                            try {
7764                                targetUid = AppGlobals.getPackageManager()
7765                                        .getPackageUid(targetPkg, targetUserId);
7766                            } catch (RemoteException e) {
7767                            }
7768                            if (targetUid != -1) {
7769                                final UriPermission perm = findOrCreateUriPermissionLocked(
7770                                        sourcePkg, targetPkg, targetUid,
7771                                        new GrantUri(sourceUserId, uri, prefix));
7772                                perm.initPersistedModes(modeFlags, createdTime);
7773                            }
7774                        } else {
7775                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7776                                    + " but instead found " + pi);
7777                        }
7778                    }
7779                }
7780            }
7781        } catch (FileNotFoundException e) {
7782            // Missing grants is okay
7783        } catch (IOException e) {
7784            Slog.wtf(TAG, "Failed reading Uri grants", e);
7785        } catch (XmlPullParserException e) {
7786            Slog.wtf(TAG, "Failed reading Uri grants", e);
7787        } finally {
7788            IoUtils.closeQuietly(fis);
7789        }
7790    }
7791
7792    /**
7793     * @param uri This uri must NOT contain an embedded userId.
7794     * @param userId The userId in which the uri is to be resolved.
7795     */
7796    @Override
7797    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7798        enforceNotIsolatedCaller("takePersistableUriPermission");
7799
7800        Preconditions.checkFlagsArgument(modeFlags,
7801                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7802
7803        synchronized (this) {
7804            final int callingUid = Binder.getCallingUid();
7805            boolean persistChanged = false;
7806            GrantUri grantUri = new GrantUri(userId, uri, false);
7807
7808            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7809                    new GrantUri(userId, uri, false));
7810            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7811                    new GrantUri(userId, uri, true));
7812
7813            final boolean exactValid = (exactPerm != null)
7814                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7815            final boolean prefixValid = (prefixPerm != null)
7816                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7817
7818            if (!(exactValid || prefixValid)) {
7819                throw new SecurityException("No persistable permission grants found for UID "
7820                        + callingUid + " and Uri " + grantUri.toSafeString());
7821            }
7822
7823            if (exactValid) {
7824                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7825            }
7826            if (prefixValid) {
7827                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7828            }
7829
7830            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7831
7832            if (persistChanged) {
7833                schedulePersistUriGrants();
7834            }
7835        }
7836    }
7837
7838    /**
7839     * @param uri This uri must NOT contain an embedded userId.
7840     * @param userId The userId in which the uri is to be resolved.
7841     */
7842    @Override
7843    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7844        enforceNotIsolatedCaller("releasePersistableUriPermission");
7845
7846        Preconditions.checkFlagsArgument(modeFlags,
7847                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7848
7849        synchronized (this) {
7850            final int callingUid = Binder.getCallingUid();
7851            boolean persistChanged = false;
7852
7853            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7854                    new GrantUri(userId, uri, false));
7855            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7856                    new GrantUri(userId, uri, true));
7857            if (exactPerm == null && prefixPerm == null) {
7858                throw new SecurityException("No permission grants found for UID " + callingUid
7859                        + " and Uri " + uri.toSafeString());
7860            }
7861
7862            if (exactPerm != null) {
7863                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7864                removeUriPermissionIfNeededLocked(exactPerm);
7865            }
7866            if (prefixPerm != null) {
7867                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7868                removeUriPermissionIfNeededLocked(prefixPerm);
7869            }
7870
7871            if (persistChanged) {
7872                schedulePersistUriGrants();
7873            }
7874        }
7875    }
7876
7877    /**
7878     * Prune any older {@link UriPermission} for the given UID until outstanding
7879     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7880     *
7881     * @return if any mutations occured that require persisting.
7882     */
7883    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7884        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7885        if (perms == null) return false;
7886        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7887
7888        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7889        for (UriPermission perm : perms.values()) {
7890            if (perm.persistedModeFlags != 0) {
7891                persisted.add(perm);
7892            }
7893        }
7894
7895        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7896        if (trimCount <= 0) return false;
7897
7898        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7899        for (int i = 0; i < trimCount; i++) {
7900            final UriPermission perm = persisted.get(i);
7901
7902            if (DEBUG_URI_PERMISSION) {
7903                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7904            }
7905
7906            perm.releasePersistableModes(~0);
7907            removeUriPermissionIfNeededLocked(perm);
7908        }
7909
7910        return true;
7911    }
7912
7913    @Override
7914    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7915            String packageName, boolean incoming) {
7916        enforceNotIsolatedCaller("getPersistedUriPermissions");
7917        Preconditions.checkNotNull(packageName, "packageName");
7918
7919        final int callingUid = Binder.getCallingUid();
7920        final IPackageManager pm = AppGlobals.getPackageManager();
7921        try {
7922            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7923            if (packageUid != callingUid) {
7924                throw new SecurityException(
7925                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7926            }
7927        } catch (RemoteException e) {
7928            throw new SecurityException("Failed to verify package name ownership");
7929        }
7930
7931        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7932        synchronized (this) {
7933            if (incoming) {
7934                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7935                        callingUid);
7936                if (perms == null) {
7937                    Slog.w(TAG, "No permission grants found for " + packageName);
7938                } else {
7939                    for (UriPermission perm : perms.values()) {
7940                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7941                            result.add(perm.buildPersistedPublicApiObject());
7942                        }
7943                    }
7944                }
7945            } else {
7946                final int size = mGrantedUriPermissions.size();
7947                for (int i = 0; i < size; i++) {
7948                    final ArrayMap<GrantUri, UriPermission> perms =
7949                            mGrantedUriPermissions.valueAt(i);
7950                    for (UriPermission perm : perms.values()) {
7951                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7952                            result.add(perm.buildPersistedPublicApiObject());
7953                        }
7954                    }
7955                }
7956            }
7957        }
7958        return new ParceledListSlice<android.content.UriPermission>(result);
7959    }
7960
7961    @Override
7962    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7963        synchronized (this) {
7964            ProcessRecord app =
7965                who != null ? getRecordForAppLocked(who) : null;
7966            if (app == null) return;
7967
7968            Message msg = Message.obtain();
7969            msg.what = WAIT_FOR_DEBUGGER_MSG;
7970            msg.obj = app;
7971            msg.arg1 = waiting ? 1 : 0;
7972            mHandler.sendMessage(msg);
7973        }
7974    }
7975
7976    @Override
7977    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7978        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7979        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7980        outInfo.availMem = Process.getFreeMemory();
7981        outInfo.totalMem = Process.getTotalMemory();
7982        outInfo.threshold = homeAppMem;
7983        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7984        outInfo.hiddenAppThreshold = cachedAppMem;
7985        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7986                ProcessList.SERVICE_ADJ);
7987        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7988                ProcessList.VISIBLE_APP_ADJ);
7989        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7990                ProcessList.FOREGROUND_APP_ADJ);
7991    }
7992
7993    // =========================================================
7994    // TASK MANAGEMENT
7995    // =========================================================
7996
7997    @Override
7998    public List<IAppTask> getAppTasks(String callingPackage) {
7999        int callingUid = Binder.getCallingUid();
8000        long ident = Binder.clearCallingIdentity();
8001
8002        synchronized(this) {
8003            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8004            try {
8005                if (localLOGV) Slog.v(TAG, "getAppTasks");
8006
8007                final int N = mRecentTasks.size();
8008                for (int i = 0; i < N; i++) {
8009                    TaskRecord tr = mRecentTasks.get(i);
8010                    // Skip tasks that do not match the caller.  We don't need to verify
8011                    // callingPackage, because we are also limiting to callingUid and know
8012                    // that will limit to the correct security sandbox.
8013                    if (tr.effectiveUid != callingUid) {
8014                        continue;
8015                    }
8016                    Intent intent = tr.getBaseIntent();
8017                    if (intent == null ||
8018                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8019                        continue;
8020                    }
8021                    ActivityManager.RecentTaskInfo taskInfo =
8022                            createRecentTaskInfoFromTaskRecord(tr);
8023                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8024                    list.add(taskImpl);
8025                }
8026            } finally {
8027                Binder.restoreCallingIdentity(ident);
8028            }
8029            return list;
8030        }
8031    }
8032
8033    @Override
8034    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8035        final int callingUid = Binder.getCallingUid();
8036        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8037
8038        synchronized(this) {
8039            if (localLOGV) Slog.v(
8040                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8041
8042            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8043                    callingUid);
8044
8045            // TODO: Improve with MRU list from all ActivityStacks.
8046            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8047        }
8048
8049        return list;
8050    }
8051
8052    /**
8053     * Creates a new RecentTaskInfo from a TaskRecord.
8054     */
8055    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8056        // Update the task description to reflect any changes in the task stack
8057        tr.updateTaskDescription();
8058
8059        // Compose the recent task info
8060        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8061        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8062        rti.persistentId = tr.taskId;
8063        rti.baseIntent = new Intent(tr.getBaseIntent());
8064        rti.origActivity = tr.origActivity;
8065        rti.description = tr.lastDescription;
8066        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8067        rti.userId = tr.userId;
8068        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8069        rti.firstActiveTime = tr.firstActiveTime;
8070        rti.lastActiveTime = tr.lastActiveTime;
8071        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8072        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8073        return rti;
8074    }
8075
8076    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8077        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8078                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8079        if (!allowed) {
8080            if (checkPermission(android.Manifest.permission.GET_TASKS,
8081                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8082                // Temporary compatibility: some existing apps on the system image may
8083                // still be requesting the old permission and not switched to the new
8084                // one; if so, we'll still allow them full access.  This means we need
8085                // to see if they are holding the old permission and are a system app.
8086                try {
8087                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8088                        allowed = true;
8089                        Slog.w(TAG, caller + ": caller " + callingUid
8090                                + " is using old GET_TASKS but privileged; allowing");
8091                    }
8092                } catch (RemoteException e) {
8093                }
8094            }
8095        }
8096        if (!allowed) {
8097            Slog.w(TAG, caller + ": caller " + callingUid
8098                    + " does not hold GET_TASKS; limiting output");
8099        }
8100        return allowed;
8101    }
8102
8103    @Override
8104    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8105        final int callingUid = Binder.getCallingUid();
8106        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8107                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8108
8109        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8110        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8111        synchronized (this) {
8112            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8113                    callingUid);
8114            final boolean detailed = checkCallingPermission(
8115                    android.Manifest.permission.GET_DETAILED_TASKS)
8116                    == PackageManager.PERMISSION_GRANTED;
8117
8118            final int N = mRecentTasks.size();
8119            ArrayList<ActivityManager.RecentTaskInfo> res
8120                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8121                            maxNum < N ? maxNum : N);
8122
8123            final Set<Integer> includedUsers;
8124            if (includeProfiles) {
8125                includedUsers = getProfileIdsLocked(userId);
8126            } else {
8127                includedUsers = new HashSet<Integer>();
8128            }
8129            includedUsers.add(Integer.valueOf(userId));
8130
8131            for (int i=0; i<N && maxNum > 0; i++) {
8132                TaskRecord tr = mRecentTasks.get(i);
8133                // Only add calling user or related users recent tasks
8134                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8135                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8136                    continue;
8137                }
8138
8139                // Return the entry if desired by the caller.  We always return
8140                // the first entry, because callers always expect this to be the
8141                // foreground app.  We may filter others if the caller has
8142                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8143                // we should exclude the entry.
8144
8145                if (i == 0
8146                        || withExcluded
8147                        || (tr.intent == null)
8148                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8149                                == 0)) {
8150                    if (!allowed) {
8151                        // If the caller doesn't have the GET_TASKS permission, then only
8152                        // allow them to see a small subset of tasks -- their own and home.
8153                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8154                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8155                            continue;
8156                        }
8157                    }
8158                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8159                        if (tr.stack != null && tr.stack.isHomeStack()) {
8160                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8161                            continue;
8162                        }
8163                    }
8164                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8165                        // Don't include auto remove tasks that are finished or finishing.
8166                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8167                                + tr);
8168                        continue;
8169                    }
8170                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8171                            && !tr.isAvailable) {
8172                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8173                        continue;
8174                    }
8175
8176                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8177                    if (!detailed) {
8178                        rti.baseIntent.replaceExtras((Bundle)null);
8179                    }
8180
8181                    res.add(rti);
8182                    maxNum--;
8183                }
8184            }
8185            return res;
8186        }
8187    }
8188
8189    TaskRecord recentTaskForIdLocked(int id) {
8190        final int N = mRecentTasks.size();
8191            for (int i=0; i<N; i++) {
8192                TaskRecord tr = mRecentTasks.get(i);
8193                if (tr.taskId == id) {
8194                    return tr;
8195                }
8196            }
8197            return null;
8198    }
8199
8200    @Override
8201    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8202        synchronized (this) {
8203            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8204                    "getTaskThumbnail()");
8205            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8206            if (tr != null) {
8207                return tr.getTaskThumbnailLocked();
8208            }
8209        }
8210        return null;
8211    }
8212
8213    @Override
8214    public int addAppTask(IBinder activityToken, Intent intent,
8215            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8216        final int callingUid = Binder.getCallingUid();
8217        final long callingIdent = Binder.clearCallingIdentity();
8218
8219        try {
8220            synchronized (this) {
8221                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8222                if (r == null) {
8223                    throw new IllegalArgumentException("Activity does not exist; token="
8224                            + activityToken);
8225                }
8226                ComponentName comp = intent.getComponent();
8227                if (comp == null) {
8228                    throw new IllegalArgumentException("Intent " + intent
8229                            + " must specify explicit component");
8230                }
8231                if (thumbnail.getWidth() != mThumbnailWidth
8232                        || thumbnail.getHeight() != mThumbnailHeight) {
8233                    throw new IllegalArgumentException("Bad thumbnail size: got "
8234                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8235                            + mThumbnailWidth + "x" + mThumbnailHeight);
8236                }
8237                if (intent.getSelector() != null) {
8238                    intent.setSelector(null);
8239                }
8240                if (intent.getSourceBounds() != null) {
8241                    intent.setSourceBounds(null);
8242                }
8243                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8244                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8245                        // The caller has added this as an auto-remove task...  that makes no
8246                        // sense, so turn off auto-remove.
8247                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8248                    }
8249                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8250                    // Must be a new task.
8251                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8252                }
8253                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8254                    mLastAddedTaskActivity = null;
8255                }
8256                ActivityInfo ainfo = mLastAddedTaskActivity;
8257                if (ainfo == null) {
8258                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8259                            comp, 0, UserHandle.getUserId(callingUid));
8260                    if (ainfo.applicationInfo.uid != callingUid) {
8261                        throw new SecurityException(
8262                                "Can't add task for another application: target uid="
8263                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8264                    }
8265                }
8266
8267                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8268                        intent, description);
8269
8270                int trimIdx = trimRecentsForTaskLocked(task, false);
8271                if (trimIdx >= 0) {
8272                    // If this would have caused a trim, then we'll abort because that
8273                    // means it would be added at the end of the list but then just removed.
8274                    return INVALID_TASK_ID;
8275                }
8276
8277                final int N = mRecentTasks.size();
8278                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8279                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8280                    tr.removedFromRecents();
8281                }
8282
8283                task.inRecents = true;
8284                mRecentTasks.add(task);
8285                r.task.stack.addTask(task, false, false);
8286
8287                task.setLastThumbnail(thumbnail);
8288                task.freeLastThumbnail();
8289
8290                return task.taskId;
8291            }
8292        } finally {
8293            Binder.restoreCallingIdentity(callingIdent);
8294        }
8295    }
8296
8297    @Override
8298    public Point getAppTaskThumbnailSize() {
8299        synchronized (this) {
8300            return new Point(mThumbnailWidth,  mThumbnailHeight);
8301        }
8302    }
8303
8304    @Override
8305    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8306        synchronized (this) {
8307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8308            if (r != null) {
8309                r.setTaskDescription(td);
8310                r.task.updateTaskDescription();
8311            }
8312        }
8313    }
8314
8315    @Override
8316    public Bitmap getTaskDescriptionIcon(String filename) {
8317        if (!FileUtils.isValidExtFilename(filename)
8318                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8319            throw new IllegalArgumentException("Bad filename: " + filename);
8320        }
8321        return mTaskPersister.getTaskDescriptionIcon(filename);
8322    }
8323
8324    @Override
8325    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8326            throws RemoteException {
8327        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8328                opts.getCustomInPlaceResId() == 0) {
8329            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8330                    "with valid animation");
8331        }
8332        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8333        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8334                opts.getCustomInPlaceResId());
8335        mWindowManager.executeAppTransition();
8336    }
8337
8338    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8339        mRecentTasks.remove(tr);
8340        tr.removedFromRecents();
8341        ComponentName component = tr.getBaseIntent().getComponent();
8342        if (component == null) {
8343            Slog.w(TAG, "No component for base intent of task: " + tr);
8344            return;
8345        }
8346
8347        if (!killProcess) {
8348            return;
8349        }
8350
8351        // Determine if the process(es) for this task should be killed.
8352        final String pkg = component.getPackageName();
8353        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8354        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8355        for (int i = 0; i < pmap.size(); i++) {
8356
8357            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8358            for (int j = 0; j < uids.size(); j++) {
8359                ProcessRecord proc = uids.valueAt(j);
8360                if (proc.userId != tr.userId) {
8361                    // Don't kill process for a different user.
8362                    continue;
8363                }
8364                if (proc == mHomeProcess) {
8365                    // Don't kill the home process along with tasks from the same package.
8366                    continue;
8367                }
8368                if (!proc.pkgList.containsKey(pkg)) {
8369                    // Don't kill process that is not associated with this task.
8370                    continue;
8371                }
8372
8373                for (int k = 0; k < proc.activities.size(); k++) {
8374                    TaskRecord otherTask = proc.activities.get(k).task;
8375                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8376                        // Don't kill process(es) that has an activity in a different task that is
8377                        // also in recents.
8378                        return;
8379                    }
8380                }
8381
8382                // Add process to kill list.
8383                procsToKill.add(proc);
8384            }
8385        }
8386
8387        // Find any running services associated with this app and stop if needed.
8388        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8389
8390        // Kill the running processes.
8391        for (int i = 0; i < procsToKill.size(); i++) {
8392            ProcessRecord pr = procsToKill.get(i);
8393            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8394                pr.kill("remove task", true);
8395            } else {
8396                pr.waitingToKill = "remove task";
8397            }
8398        }
8399    }
8400
8401    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8402        // Remove all tasks with activities in the specified package from the list of recent tasks
8403        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8404            TaskRecord tr = mRecentTasks.get(i);
8405            if (tr.userId != userId) continue;
8406
8407            ComponentName cn = tr.intent.getComponent();
8408            if (cn != null && cn.getPackageName().equals(packageName)) {
8409                // If the package name matches, remove the task.
8410                removeTaskByIdLocked(tr.taskId, true);
8411            }
8412        }
8413    }
8414
8415    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8416        final IPackageManager pm = AppGlobals.getPackageManager();
8417        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8418
8419        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8420            TaskRecord tr = mRecentTasks.get(i);
8421            if (tr.userId != userId) continue;
8422
8423            ComponentName cn = tr.intent.getComponent();
8424            if (cn != null && cn.getPackageName().equals(packageName)) {
8425                // Skip if component still exists in the package.
8426                if (componentsKnownToExist.contains(cn)) continue;
8427
8428                try {
8429                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8430                    if (info != null) {
8431                        componentsKnownToExist.add(cn);
8432                    } else {
8433                        removeTaskByIdLocked(tr.taskId, false);
8434                    }
8435                } catch (RemoteException e) {
8436                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8437                }
8438            }
8439        }
8440    }
8441
8442    /**
8443     * Removes the task with the specified task id.
8444     *
8445     * @param taskId Identifier of the task to be removed.
8446     * @param killProcess Kill any process associated with the task if possible.
8447     * @return Returns true if the given task was found and removed.
8448     */
8449    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8450        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8451        if (tr != null) {
8452            tr.removeTaskActivitiesLocked();
8453            cleanUpRemovedTaskLocked(tr, killProcess);
8454            if (tr.isPersistable) {
8455                notifyTaskPersisterLocked(null, true);
8456            }
8457            return true;
8458        }
8459        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8460        return false;
8461    }
8462
8463    @Override
8464    public boolean removeTask(int taskId) {
8465        synchronized (this) {
8466            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8467                    "removeTask()");
8468            long ident = Binder.clearCallingIdentity();
8469            try {
8470                return removeTaskByIdLocked(taskId, true);
8471            } finally {
8472                Binder.restoreCallingIdentity(ident);
8473            }
8474        }
8475    }
8476
8477    /**
8478     * TODO: Add mController hook
8479     */
8480    @Override
8481    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8482        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8483                "moveTaskToFront()");
8484
8485        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8486        synchronized(this) {
8487            moveTaskToFrontLocked(taskId, flags, options);
8488        }
8489    }
8490
8491    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8492        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8493                Binder.getCallingUid(), -1, -1, "Task to front")) {
8494            ActivityOptions.abort(options);
8495            return;
8496        }
8497        final long origId = Binder.clearCallingIdentity();
8498        try {
8499            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8500            if (task == null) {
8501                Slog.d(TAG, "Could not find task for id: "+ taskId);
8502                return;
8503            }
8504            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8505                mStackSupervisor.showLockTaskToast();
8506                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8507                return;
8508            }
8509            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8510            if (prev != null && prev.isRecentsActivity()) {
8511                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8512            }
8513            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8514        } finally {
8515            Binder.restoreCallingIdentity(origId);
8516        }
8517        ActivityOptions.abort(options);
8518    }
8519
8520    @Override
8521    public void moveTaskToBack(int taskId) {
8522        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8523                "moveTaskToBack()");
8524
8525        synchronized(this) {
8526            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8527            if (tr != null) {
8528                if (tr == mStackSupervisor.mLockTaskModeTask) {
8529                    mStackSupervisor.showLockTaskToast();
8530                    return;
8531                }
8532                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8533                ActivityStack stack = tr.stack;
8534                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8535                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8536                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8537                        return;
8538                    }
8539                }
8540                final long origId = Binder.clearCallingIdentity();
8541                try {
8542                    stack.moveTaskToBackLocked(taskId, null);
8543                } finally {
8544                    Binder.restoreCallingIdentity(origId);
8545                }
8546            }
8547        }
8548    }
8549
8550    /**
8551     * Moves an activity, and all of the other activities within the same task, to the bottom
8552     * of the history stack.  The activity's order within the task is unchanged.
8553     *
8554     * @param token A reference to the activity we wish to move
8555     * @param nonRoot If false then this only works if the activity is the root
8556     *                of a task; if true it will work for any activity in a task.
8557     * @return Returns true if the move completed, false if not.
8558     */
8559    @Override
8560    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8561        enforceNotIsolatedCaller("moveActivityTaskToBack");
8562        synchronized(this) {
8563            final long origId = Binder.clearCallingIdentity();
8564            try {
8565                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8566                if (taskId >= 0) {
8567                    if ((mStackSupervisor.mLockTaskModeTask != null)
8568                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8569                        mStackSupervisor.showLockTaskToast();
8570                        return false;
8571                    }
8572                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8573                }
8574            } finally {
8575                Binder.restoreCallingIdentity(origId);
8576            }
8577        }
8578        return false;
8579    }
8580
8581    @Override
8582    public void moveTaskBackwards(int task) {
8583        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8584                "moveTaskBackwards()");
8585
8586        synchronized(this) {
8587            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8588                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8589                return;
8590            }
8591            final long origId = Binder.clearCallingIdentity();
8592            moveTaskBackwardsLocked(task);
8593            Binder.restoreCallingIdentity(origId);
8594        }
8595    }
8596
8597    private final void moveTaskBackwardsLocked(int task) {
8598        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8599    }
8600
8601    @Override
8602    public IBinder getHomeActivityToken() throws RemoteException {
8603        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8604                "getHomeActivityToken()");
8605        synchronized (this) {
8606            return mStackSupervisor.getHomeActivityToken();
8607        }
8608    }
8609
8610    @Override
8611    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8612            IActivityContainerCallback callback) throws RemoteException {
8613        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8614                "createActivityContainer()");
8615        synchronized (this) {
8616            if (parentActivityToken == null) {
8617                throw new IllegalArgumentException("parent token must not be null");
8618            }
8619            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8620            if (r == null) {
8621                return null;
8622            }
8623            if (callback == null) {
8624                throw new IllegalArgumentException("callback must not be null");
8625            }
8626            return mStackSupervisor.createActivityContainer(r, callback);
8627        }
8628    }
8629
8630    @Override
8631    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8632        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8633                "deleteActivityContainer()");
8634        synchronized (this) {
8635            mStackSupervisor.deleteActivityContainer(container);
8636        }
8637    }
8638
8639    @Override
8640    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8641            throws RemoteException {
8642        synchronized (this) {
8643            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8644            if (stack != null) {
8645                return stack.mActivityContainer;
8646            }
8647            return null;
8648        }
8649    }
8650
8651    @Override
8652    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8653        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8654                "moveTaskToStack()");
8655        if (stackId == HOME_STACK_ID) {
8656            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8657                    new RuntimeException("here").fillInStackTrace());
8658        }
8659        synchronized (this) {
8660            long ident = Binder.clearCallingIdentity();
8661            try {
8662                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8663                        + stackId + " toTop=" + toTop);
8664                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8665            } finally {
8666                Binder.restoreCallingIdentity(ident);
8667            }
8668        }
8669    }
8670
8671    @Override
8672    public void resizeStack(int stackBoxId, Rect bounds) {
8673        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8674                "resizeStackBox()");
8675        long ident = Binder.clearCallingIdentity();
8676        try {
8677            mWindowManager.resizeStack(stackBoxId, bounds);
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681    }
8682
8683    @Override
8684    public List<StackInfo> getAllStackInfos() {
8685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8686                "getAllStackInfos()");
8687        long ident = Binder.clearCallingIdentity();
8688        try {
8689            synchronized (this) {
8690                return mStackSupervisor.getAllStackInfosLocked();
8691            }
8692        } finally {
8693            Binder.restoreCallingIdentity(ident);
8694        }
8695    }
8696
8697    @Override
8698    public StackInfo getStackInfo(int stackId) {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "getStackInfo()");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            synchronized (this) {
8704                return mStackSupervisor.getStackInfoLocked(stackId);
8705            }
8706        } finally {
8707            Binder.restoreCallingIdentity(ident);
8708        }
8709    }
8710
8711    @Override
8712    public boolean isInHomeStack(int taskId) {
8713        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8714                "getStackInfo()");
8715        long ident = Binder.clearCallingIdentity();
8716        try {
8717            synchronized (this) {
8718                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8719                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8720            }
8721        } finally {
8722            Binder.restoreCallingIdentity(ident);
8723        }
8724    }
8725
8726    @Override
8727    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8728        synchronized(this) {
8729            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8730        }
8731    }
8732
8733    private boolean isLockTaskAuthorized(String pkg) {
8734        final DevicePolicyManager dpm = (DevicePolicyManager)
8735                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8736        try {
8737            int uid = mContext.getPackageManager().getPackageUid(pkg,
8738                    Binder.getCallingUserHandle().getIdentifier());
8739            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8740        } catch (NameNotFoundException e) {
8741            return false;
8742        }
8743    }
8744
8745    void startLockTaskMode(TaskRecord task) {
8746        final String pkg;
8747        synchronized (this) {
8748            pkg = task.intent.getComponent().getPackageName();
8749        }
8750        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8751        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8752            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8753                    StatusBarManagerInternal.class);
8754            if (statusBarManager != null) {
8755                statusBarManager.showScreenPinningRequest();
8756            }
8757            return;
8758        }
8759        long ident = Binder.clearCallingIdentity();
8760        try {
8761            synchronized (this) {
8762                // Since we lost lock on task, make sure it is still there.
8763                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8764                if (task != null) {
8765                    if (!isSystemInitiated
8766                            && ((mStackSupervisor.getFocusedStack() == null)
8767                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8768                        throw new IllegalArgumentException("Invalid task, not in foreground");
8769                    }
8770                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8771                }
8772            }
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776    }
8777
8778    @Override
8779    public void startLockTaskMode(int taskId) {
8780        final TaskRecord task;
8781        long ident = Binder.clearCallingIdentity();
8782        try {
8783            synchronized (this) {
8784                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8785            }
8786        } finally {
8787            Binder.restoreCallingIdentity(ident);
8788        }
8789        if (task != null) {
8790            startLockTaskMode(task);
8791        }
8792    }
8793
8794    @Override
8795    public void startLockTaskMode(IBinder token) {
8796        final TaskRecord task;
8797        long ident = Binder.clearCallingIdentity();
8798        try {
8799            synchronized (this) {
8800                final ActivityRecord r = ActivityRecord.forToken(token);
8801                if (r == null) {
8802                    return;
8803                }
8804                task = r.task;
8805            }
8806        } finally {
8807            Binder.restoreCallingIdentity(ident);
8808        }
8809        if (task != null) {
8810            startLockTaskMode(task);
8811        }
8812    }
8813
8814    @Override
8815    public void startLockTaskModeOnCurrent() throws RemoteException {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "startLockTaskModeOnCurrent");
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            ActivityRecord r = null;
8821            synchronized (this) {
8822                r = mStackSupervisor.topRunningActivityLocked();
8823            }
8824            startLockTaskMode(r.task);
8825        } finally {
8826            Binder.restoreCallingIdentity(ident);
8827        }
8828    }
8829
8830    @Override
8831    public void stopLockTaskMode() {
8832        // Verify that the user matches the package of the intent for the TaskRecord
8833        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8834        // and stopLockTaskMode.
8835        final int callingUid = Binder.getCallingUid();
8836        if (callingUid != Process.SYSTEM_UID) {
8837            try {
8838                String pkg =
8839                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8840                int uid = mContext.getPackageManager().getPackageUid(pkg,
8841                        Binder.getCallingUserHandle().getIdentifier());
8842                if (uid != callingUid) {
8843                    throw new SecurityException("Invalid uid, expected " + uid);
8844                }
8845            } catch (NameNotFoundException e) {
8846                Log.d(TAG, "stopLockTaskMode " + e);
8847                return;
8848            }
8849        }
8850        long ident = Binder.clearCallingIdentity();
8851        try {
8852            Log.d(TAG, "stopLockTaskMode");
8853            // Stop lock task
8854            synchronized (this) {
8855                mStackSupervisor.setLockTaskModeLocked(null, false);
8856            }
8857        } finally {
8858            Binder.restoreCallingIdentity(ident);
8859        }
8860    }
8861
8862    @Override
8863    public void stopLockTaskModeOnCurrent() throws RemoteException {
8864        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8865                "stopLockTaskModeOnCurrent");
8866        long ident = Binder.clearCallingIdentity();
8867        try {
8868            stopLockTaskMode();
8869        } finally {
8870            Binder.restoreCallingIdentity(ident);
8871        }
8872    }
8873
8874    @Override
8875    public boolean isInLockTaskMode() {
8876        synchronized (this) {
8877            return mStackSupervisor.isInLockTaskMode();
8878        }
8879    }
8880
8881    // =========================================================
8882    // CONTENT PROVIDERS
8883    // =========================================================
8884
8885    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8886        List<ProviderInfo> providers = null;
8887        try {
8888            providers = AppGlobals.getPackageManager().
8889                queryContentProviders(app.processName, app.uid,
8890                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8891        } catch (RemoteException ex) {
8892        }
8893        if (DEBUG_MU)
8894            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8895        int userId = app.userId;
8896        if (providers != null) {
8897            int N = providers.size();
8898            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8899            for (int i=0; i<N; i++) {
8900                ProviderInfo cpi =
8901                    (ProviderInfo)providers.get(i);
8902                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8903                        cpi.name, cpi.flags);
8904                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8905                    // This is a singleton provider, but a user besides the
8906                    // default user is asking to initialize a process it runs
8907                    // in...  well, no, it doesn't actually run in this process,
8908                    // it runs in the process of the default user.  Get rid of it.
8909                    providers.remove(i);
8910                    N--;
8911                    i--;
8912                    continue;
8913                }
8914
8915                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8916                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8917                if (cpr == null) {
8918                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8919                    mProviderMap.putProviderByClass(comp, cpr);
8920                }
8921                if (DEBUG_MU)
8922                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8923                app.pubProviders.put(cpi.name, cpr);
8924                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8925                    // Don't add this if it is a platform component that is marked
8926                    // to run in multiple processes, because this is actually
8927                    // part of the framework so doesn't make sense to track as a
8928                    // separate apk in the process.
8929                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8930                            mProcessStats);
8931                }
8932                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8933            }
8934        }
8935        return providers;
8936    }
8937
8938    /**
8939     * Check if {@link ProcessRecord} has a possible chance at accessing the
8940     * given {@link ProviderInfo}. Final permission checking is always done
8941     * in {@link ContentProvider}.
8942     */
8943    private final String checkContentProviderPermissionLocked(
8944            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8945        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8946        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8947        boolean checkedGrants = false;
8948        if (checkUser) {
8949            // Looking for cross-user grants before enforcing the typical cross-users permissions
8950            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8951            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8952                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8953                    return null;
8954                }
8955                checkedGrants = true;
8956            }
8957            userId = handleIncomingUser(callingPid, callingUid, userId,
8958                    false, ALLOW_NON_FULL,
8959                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8960            if (userId != tmpTargetUserId) {
8961                // When we actually went to determine the final targer user ID, this ended
8962                // up different than our initial check for the authority.  This is because
8963                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8964                // SELF.  So we need to re-check the grants again.
8965                checkedGrants = false;
8966            }
8967        }
8968        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8969                cpi.applicationInfo.uid, cpi.exported)
8970                == PackageManager.PERMISSION_GRANTED) {
8971            return null;
8972        }
8973        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8974                cpi.applicationInfo.uid, cpi.exported)
8975                == PackageManager.PERMISSION_GRANTED) {
8976            return null;
8977        }
8978
8979        PathPermission[] pps = cpi.pathPermissions;
8980        if (pps != null) {
8981            int i = pps.length;
8982            while (i > 0) {
8983                i--;
8984                PathPermission pp = pps[i];
8985                String pprperm = pp.getReadPermission();
8986                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8987                        cpi.applicationInfo.uid, cpi.exported)
8988                        == PackageManager.PERMISSION_GRANTED) {
8989                    return null;
8990                }
8991                String ppwperm = pp.getWritePermission();
8992                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8993                        cpi.applicationInfo.uid, cpi.exported)
8994                        == PackageManager.PERMISSION_GRANTED) {
8995                    return null;
8996                }
8997            }
8998        }
8999        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9000            return null;
9001        }
9002
9003        String msg;
9004        if (!cpi.exported) {
9005            msg = "Permission Denial: opening provider " + cpi.name
9006                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9007                    + ", uid=" + callingUid + ") that is not exported from uid "
9008                    + cpi.applicationInfo.uid;
9009        } else {
9010            msg = "Permission Denial: opening provider " + cpi.name
9011                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9012                    + ", uid=" + callingUid + ") requires "
9013                    + cpi.readPermission + " or " + cpi.writePermission;
9014        }
9015        Slog.w(TAG, msg);
9016        return msg;
9017    }
9018
9019    /**
9020     * Returns if the ContentProvider has granted a uri to callingUid
9021     */
9022    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9023        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9024        if (perms != null) {
9025            for (int i=perms.size()-1; i>=0; i--) {
9026                GrantUri grantUri = perms.keyAt(i);
9027                if (grantUri.sourceUserId == userId || !checkUser) {
9028                    if (matchesProvider(grantUri.uri, cpi)) {
9029                        return true;
9030                    }
9031                }
9032            }
9033        }
9034        return false;
9035    }
9036
9037    /**
9038     * Returns true if the uri authority is one of the authorities specified in the provider.
9039     */
9040    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9041        String uriAuth = uri.getAuthority();
9042        String cpiAuth = cpi.authority;
9043        if (cpiAuth.indexOf(';') == -1) {
9044            return cpiAuth.equals(uriAuth);
9045        }
9046        String[] cpiAuths = cpiAuth.split(";");
9047        int length = cpiAuths.length;
9048        for (int i = 0; i < length; i++) {
9049            if (cpiAuths[i].equals(uriAuth)) return true;
9050        }
9051        return false;
9052    }
9053
9054    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9055            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9056        if (r != null) {
9057            for (int i=0; i<r.conProviders.size(); i++) {
9058                ContentProviderConnection conn = r.conProviders.get(i);
9059                if (conn.provider == cpr) {
9060                    if (DEBUG_PROVIDER) Slog.v(TAG,
9061                            "Adding provider requested by "
9062                            + r.processName + " from process "
9063                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9064                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9065                    if (stable) {
9066                        conn.stableCount++;
9067                        conn.numStableIncs++;
9068                    } else {
9069                        conn.unstableCount++;
9070                        conn.numUnstableIncs++;
9071                    }
9072                    return conn;
9073                }
9074            }
9075            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9076            if (stable) {
9077                conn.stableCount = 1;
9078                conn.numStableIncs = 1;
9079            } else {
9080                conn.unstableCount = 1;
9081                conn.numUnstableIncs = 1;
9082            }
9083            cpr.connections.add(conn);
9084            r.conProviders.add(conn);
9085            return conn;
9086        }
9087        cpr.addExternalProcessHandleLocked(externalProcessToken);
9088        return null;
9089    }
9090
9091    boolean decProviderCountLocked(ContentProviderConnection conn,
9092            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9093        if (conn != null) {
9094            cpr = conn.provider;
9095            if (DEBUG_PROVIDER) Slog.v(TAG,
9096                    "Removing provider requested by "
9097                    + conn.client.processName + " from process "
9098                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9099                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9100            if (stable) {
9101                conn.stableCount--;
9102            } else {
9103                conn.unstableCount--;
9104            }
9105            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9106                cpr.connections.remove(conn);
9107                conn.client.conProviders.remove(conn);
9108                return true;
9109            }
9110            return false;
9111        }
9112        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9113        return false;
9114    }
9115
9116    private void checkTime(long startTime, String where) {
9117        long now = SystemClock.elapsedRealtime();
9118        if ((now-startTime) > 1000) {
9119            // If we are taking more than a second, log about it.
9120            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9121        }
9122    }
9123
9124    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9125            String name, IBinder token, boolean stable, int userId) {
9126        ContentProviderRecord cpr;
9127        ContentProviderConnection conn = null;
9128        ProviderInfo cpi = null;
9129
9130        synchronized(this) {
9131            long startTime = SystemClock.elapsedRealtime();
9132
9133            ProcessRecord r = null;
9134            if (caller != null) {
9135                r = getRecordForAppLocked(caller);
9136                if (r == null) {
9137                    throw new SecurityException(
9138                            "Unable to find app for caller " + caller
9139                          + " (pid=" + Binder.getCallingPid()
9140                          + ") when getting content provider " + name);
9141                }
9142            }
9143
9144            boolean checkCrossUser = true;
9145
9146            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9147
9148            // First check if this content provider has been published...
9149            cpr = mProviderMap.getProviderByName(name, userId);
9150            // If that didn't work, check if it exists for user 0 and then
9151            // verify that it's a singleton provider before using it.
9152            if (cpr == null && userId != UserHandle.USER_OWNER) {
9153                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9154                if (cpr != null) {
9155                    cpi = cpr.info;
9156                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9157                            cpi.name, cpi.flags)
9158                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9159                        userId = UserHandle.USER_OWNER;
9160                        checkCrossUser = false;
9161                    } else {
9162                        cpr = null;
9163                        cpi = null;
9164                    }
9165                }
9166            }
9167
9168            boolean providerRunning = cpr != null;
9169            if (providerRunning) {
9170                cpi = cpr.info;
9171                String msg;
9172                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9173                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9174                        != null) {
9175                    throw new SecurityException(msg);
9176                }
9177                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9178
9179                if (r != null && cpr.canRunHere(r)) {
9180                    // This provider has been published or is in the process
9181                    // of being published...  but it is also allowed to run
9182                    // in the caller's process, so don't make a connection
9183                    // and just let the caller instantiate its own instance.
9184                    ContentProviderHolder holder = cpr.newHolder(null);
9185                    // don't give caller the provider object, it needs
9186                    // to make its own.
9187                    holder.provider = null;
9188                    return holder;
9189                }
9190
9191                final long origId = Binder.clearCallingIdentity();
9192
9193                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9194
9195                // In this case the provider instance already exists, so we can
9196                // return it right away.
9197                conn = incProviderCountLocked(r, cpr, token, stable);
9198                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9199                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9200                        // If this is a perceptible app accessing the provider,
9201                        // make sure to count it as being accessed and thus
9202                        // back up on the LRU list.  This is good because
9203                        // content providers are often expensive to start.
9204                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9205                        updateLruProcessLocked(cpr.proc, false, null);
9206                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9207                    }
9208                }
9209
9210                if (cpr.proc != null) {
9211                    if (false) {
9212                        if (cpr.name.flattenToShortString().equals(
9213                                "com.android.providers.calendar/.CalendarProvider2")) {
9214                            Slog.v(TAG, "****************** KILLING "
9215                                + cpr.name.flattenToShortString());
9216                            Process.killProcess(cpr.proc.pid);
9217                        }
9218                    }
9219                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9220                    boolean success = updateOomAdjLocked(cpr.proc);
9221                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9222                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9223                    // NOTE: there is still a race here where a signal could be
9224                    // pending on the process even though we managed to update its
9225                    // adj level.  Not sure what to do about this, but at least
9226                    // the race is now smaller.
9227                    if (!success) {
9228                        // Uh oh...  it looks like the provider's process
9229                        // has been killed on us.  We need to wait for a new
9230                        // process to be started, and make sure its death
9231                        // doesn't kill our process.
9232                        Slog.i(TAG,
9233                                "Existing provider " + cpr.name.flattenToShortString()
9234                                + " is crashing; detaching " + r);
9235                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9236                        checkTime(startTime, "getContentProviderImpl: before appDied");
9237                        appDiedLocked(cpr.proc);
9238                        checkTime(startTime, "getContentProviderImpl: after appDied");
9239                        if (!lastRef) {
9240                            // This wasn't the last ref our process had on
9241                            // the provider...  we have now been killed, bail.
9242                            return null;
9243                        }
9244                        providerRunning = false;
9245                        conn = null;
9246                    }
9247                }
9248
9249                Binder.restoreCallingIdentity(origId);
9250            }
9251
9252            boolean singleton;
9253            if (!providerRunning) {
9254                try {
9255                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9256                    cpi = AppGlobals.getPackageManager().
9257                        resolveContentProvider(name,
9258                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9259                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9260                } catch (RemoteException ex) {
9261                }
9262                if (cpi == null) {
9263                    return null;
9264                }
9265                // If the provider is a singleton AND
9266                // (it's a call within the same user || the provider is a
9267                // privileged app)
9268                // Then allow connecting to the singleton provider
9269                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9270                        cpi.name, cpi.flags)
9271                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9272                if (singleton) {
9273                    userId = UserHandle.USER_OWNER;
9274                }
9275                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9276                checkTime(startTime, "getContentProviderImpl: got app info for user");
9277
9278                String msg;
9279                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9280                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9281                        != null) {
9282                    throw new SecurityException(msg);
9283                }
9284                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9285
9286                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9287                        && !cpi.processName.equals("system")) {
9288                    // If this content provider does not run in the system
9289                    // process, and the system is not yet ready to run other
9290                    // processes, then fail fast instead of hanging.
9291                    throw new IllegalArgumentException(
9292                            "Attempt to launch content provider before system ready");
9293                }
9294
9295                // Make sure that the user who owns this provider is running.  If not,
9296                // we don't want to allow it to run.
9297                if (!isUserRunningLocked(userId, false)) {
9298                    Slog.w(TAG, "Unable to launch app "
9299                            + cpi.applicationInfo.packageName + "/"
9300                            + cpi.applicationInfo.uid + " for provider "
9301                            + name + ": user " + userId + " is stopped");
9302                    return null;
9303                }
9304
9305                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9306                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9307                cpr = mProviderMap.getProviderByClass(comp, userId);
9308                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9309                final boolean firstClass = cpr == null;
9310                if (firstClass) {
9311                    final long ident = Binder.clearCallingIdentity();
9312                    try {
9313                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9314                        ApplicationInfo ai =
9315                            AppGlobals.getPackageManager().
9316                                getApplicationInfo(
9317                                        cpi.applicationInfo.packageName,
9318                                        STOCK_PM_FLAGS, userId);
9319                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9320                        if (ai == null) {
9321                            Slog.w(TAG, "No package info for content provider "
9322                                    + cpi.name);
9323                            return null;
9324                        }
9325                        ai = getAppInfoForUser(ai, userId);
9326                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9327                    } catch (RemoteException ex) {
9328                        // pm is in same process, this will never happen.
9329                    } finally {
9330                        Binder.restoreCallingIdentity(ident);
9331                    }
9332                }
9333
9334                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9335
9336                if (r != null && cpr.canRunHere(r)) {
9337                    // If this is a multiprocess provider, then just return its
9338                    // info and allow the caller to instantiate it.  Only do
9339                    // this if the provider is the same user as the caller's
9340                    // process, or can run as root (so can be in any process).
9341                    return cpr.newHolder(null);
9342                }
9343
9344                if (DEBUG_PROVIDER) {
9345                    RuntimeException e = new RuntimeException("here");
9346                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9347                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9348                }
9349
9350                // This is single process, and our app is now connecting to it.
9351                // See if we are already in the process of launching this
9352                // provider.
9353                final int N = mLaunchingProviders.size();
9354                int i;
9355                for (i=0; i<N; i++) {
9356                    if (mLaunchingProviders.get(i) == cpr) {
9357                        break;
9358                    }
9359                }
9360
9361                // If the provider is not already being launched, then get it
9362                // started.
9363                if (i >= N) {
9364                    final long origId = Binder.clearCallingIdentity();
9365
9366                    try {
9367                        // Content provider is now in use, its package can't be stopped.
9368                        try {
9369                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9370                            AppGlobals.getPackageManager().setPackageStoppedState(
9371                                    cpr.appInfo.packageName, false, userId);
9372                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9373                        } catch (RemoteException e) {
9374                        } catch (IllegalArgumentException e) {
9375                            Slog.w(TAG, "Failed trying to unstop package "
9376                                    + cpr.appInfo.packageName + ": " + e);
9377                        }
9378
9379                        // Use existing process if already started
9380                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9381                        ProcessRecord proc = getProcessRecordLocked(
9382                                cpi.processName, cpr.appInfo.uid, false);
9383                        if (proc != null && proc.thread != null) {
9384                            if (DEBUG_PROVIDER) {
9385                                Slog.d(TAG, "Installing in existing process " + proc);
9386                            }
9387                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9388                            proc.pubProviders.put(cpi.name, cpr);
9389                            try {
9390                                proc.thread.scheduleInstallProvider(cpi);
9391                            } catch (RemoteException e) {
9392                            }
9393                        } else {
9394                            checkTime(startTime, "getContentProviderImpl: before start process");
9395                            proc = startProcessLocked(cpi.processName,
9396                                    cpr.appInfo, false, 0, "content provider",
9397                                    new ComponentName(cpi.applicationInfo.packageName,
9398                                            cpi.name), false, false, false);
9399                            checkTime(startTime, "getContentProviderImpl: after start process");
9400                            if (proc == null) {
9401                                Slog.w(TAG, "Unable to launch app "
9402                                        + cpi.applicationInfo.packageName + "/"
9403                                        + cpi.applicationInfo.uid + " for provider "
9404                                        + name + ": process is bad");
9405                                return null;
9406                            }
9407                        }
9408                        cpr.launchingApp = proc;
9409                        mLaunchingProviders.add(cpr);
9410                    } finally {
9411                        Binder.restoreCallingIdentity(origId);
9412                    }
9413                }
9414
9415                checkTime(startTime, "getContentProviderImpl: updating data structures");
9416
9417                // Make sure the provider is published (the same provider class
9418                // may be published under multiple names).
9419                if (firstClass) {
9420                    mProviderMap.putProviderByClass(comp, cpr);
9421                }
9422
9423                mProviderMap.putProviderByName(name, cpr);
9424                conn = incProviderCountLocked(r, cpr, token, stable);
9425                if (conn != null) {
9426                    conn.waiting = true;
9427                }
9428            }
9429            checkTime(startTime, "getContentProviderImpl: done!");
9430        }
9431
9432        // Wait for the provider to be published...
9433        synchronized (cpr) {
9434            while (cpr.provider == null) {
9435                if (cpr.launchingApp == null) {
9436                    Slog.w(TAG, "Unable to launch app "
9437                            + cpi.applicationInfo.packageName + "/"
9438                            + cpi.applicationInfo.uid + " for provider "
9439                            + name + ": launching app became null");
9440                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9441                            UserHandle.getUserId(cpi.applicationInfo.uid),
9442                            cpi.applicationInfo.packageName,
9443                            cpi.applicationInfo.uid, name);
9444                    return null;
9445                }
9446                try {
9447                    if (DEBUG_MU) {
9448                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9449                                + cpr.launchingApp);
9450                    }
9451                    if (conn != null) {
9452                        conn.waiting = true;
9453                    }
9454                    cpr.wait();
9455                } catch (InterruptedException ex) {
9456                } finally {
9457                    if (conn != null) {
9458                        conn.waiting = false;
9459                    }
9460                }
9461            }
9462        }
9463        return cpr != null ? cpr.newHolder(conn) : null;
9464    }
9465
9466    @Override
9467    public final ContentProviderHolder getContentProvider(
9468            IApplicationThread caller, String name, int userId, boolean stable) {
9469        enforceNotIsolatedCaller("getContentProvider");
9470        if (caller == null) {
9471            String msg = "null IApplicationThread when getting content provider "
9472                    + name;
9473            Slog.w(TAG, msg);
9474            throw new SecurityException(msg);
9475        }
9476        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9477        // with cross-user grant.
9478        return getContentProviderImpl(caller, name, null, stable, userId);
9479    }
9480
9481    public ContentProviderHolder getContentProviderExternal(
9482            String name, int userId, IBinder token) {
9483        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9484            "Do not have permission in call getContentProviderExternal()");
9485        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9486                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9487        return getContentProviderExternalUnchecked(name, token, userId);
9488    }
9489
9490    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9491            IBinder token, int userId) {
9492        return getContentProviderImpl(null, name, token, true, userId);
9493    }
9494
9495    /**
9496     * Drop a content provider from a ProcessRecord's bookkeeping
9497     */
9498    public void removeContentProvider(IBinder connection, boolean stable) {
9499        enforceNotIsolatedCaller("removeContentProvider");
9500        long ident = Binder.clearCallingIdentity();
9501        try {
9502            synchronized (this) {
9503                ContentProviderConnection conn;
9504                try {
9505                    conn = (ContentProviderConnection)connection;
9506                } catch (ClassCastException e) {
9507                    String msg ="removeContentProvider: " + connection
9508                            + " not a ContentProviderConnection";
9509                    Slog.w(TAG, msg);
9510                    throw new IllegalArgumentException(msg);
9511                }
9512                if (conn == null) {
9513                    throw new NullPointerException("connection is null");
9514                }
9515                if (decProviderCountLocked(conn, null, null, stable)) {
9516                    updateOomAdjLocked();
9517                }
9518            }
9519        } finally {
9520            Binder.restoreCallingIdentity(ident);
9521        }
9522    }
9523
9524    public void removeContentProviderExternal(String name, IBinder token) {
9525        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9526            "Do not have permission in call removeContentProviderExternal()");
9527        int userId = UserHandle.getCallingUserId();
9528        long ident = Binder.clearCallingIdentity();
9529        try {
9530            removeContentProviderExternalUnchecked(name, token, userId);
9531        } finally {
9532            Binder.restoreCallingIdentity(ident);
9533        }
9534    }
9535
9536    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9537        synchronized (this) {
9538            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9539            if(cpr == null) {
9540                //remove from mProvidersByClass
9541                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9542                return;
9543            }
9544
9545            //update content provider record entry info
9546            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9547            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9548            if (localCpr.hasExternalProcessHandles()) {
9549                if (localCpr.removeExternalProcessHandleLocked(token)) {
9550                    updateOomAdjLocked();
9551                } else {
9552                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9553                            + " with no external reference for token: "
9554                            + token + ".");
9555                }
9556            } else {
9557                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9558                        + " with no external references.");
9559            }
9560        }
9561    }
9562
9563    public final void publishContentProviders(IApplicationThread caller,
9564            List<ContentProviderHolder> providers) {
9565        if (providers == null) {
9566            return;
9567        }
9568
9569        enforceNotIsolatedCaller("publishContentProviders");
9570        synchronized (this) {
9571            final ProcessRecord r = getRecordForAppLocked(caller);
9572            if (DEBUG_MU)
9573                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9574            if (r == null) {
9575                throw new SecurityException(
9576                        "Unable to find app for caller " + caller
9577                      + " (pid=" + Binder.getCallingPid()
9578                      + ") when publishing content providers");
9579            }
9580
9581            final long origId = Binder.clearCallingIdentity();
9582
9583            final int N = providers.size();
9584            for (int i=0; i<N; i++) {
9585                ContentProviderHolder src = providers.get(i);
9586                if (src == null || src.info == null || src.provider == null) {
9587                    continue;
9588                }
9589                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9590                if (DEBUG_MU)
9591                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9592                if (dst != null) {
9593                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9594                    mProviderMap.putProviderByClass(comp, dst);
9595                    String names[] = dst.info.authority.split(";");
9596                    for (int j = 0; j < names.length; j++) {
9597                        mProviderMap.putProviderByName(names[j], dst);
9598                    }
9599
9600                    int NL = mLaunchingProviders.size();
9601                    int j;
9602                    for (j=0; j<NL; j++) {
9603                        if (mLaunchingProviders.get(j) == dst) {
9604                            mLaunchingProviders.remove(j);
9605                            j--;
9606                            NL--;
9607                        }
9608                    }
9609                    synchronized (dst) {
9610                        dst.provider = src.provider;
9611                        dst.proc = r;
9612                        dst.notifyAll();
9613                    }
9614                    updateOomAdjLocked(r);
9615                }
9616            }
9617
9618            Binder.restoreCallingIdentity(origId);
9619        }
9620    }
9621
9622    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9623        ContentProviderConnection conn;
9624        try {
9625            conn = (ContentProviderConnection)connection;
9626        } catch (ClassCastException e) {
9627            String msg ="refContentProvider: " + connection
9628                    + " not a ContentProviderConnection";
9629            Slog.w(TAG, msg);
9630            throw new IllegalArgumentException(msg);
9631        }
9632        if (conn == null) {
9633            throw new NullPointerException("connection is null");
9634        }
9635
9636        synchronized (this) {
9637            if (stable > 0) {
9638                conn.numStableIncs += stable;
9639            }
9640            stable = conn.stableCount + stable;
9641            if (stable < 0) {
9642                throw new IllegalStateException("stableCount < 0: " + stable);
9643            }
9644
9645            if (unstable > 0) {
9646                conn.numUnstableIncs += unstable;
9647            }
9648            unstable = conn.unstableCount + unstable;
9649            if (unstable < 0) {
9650                throw new IllegalStateException("unstableCount < 0: " + unstable);
9651            }
9652
9653            if ((stable+unstable) <= 0) {
9654                throw new IllegalStateException("ref counts can't go to zero here: stable="
9655                        + stable + " unstable=" + unstable);
9656            }
9657            conn.stableCount = stable;
9658            conn.unstableCount = unstable;
9659            return !conn.dead;
9660        }
9661    }
9662
9663    public void unstableProviderDied(IBinder connection) {
9664        ContentProviderConnection conn;
9665        try {
9666            conn = (ContentProviderConnection)connection;
9667        } catch (ClassCastException e) {
9668            String msg ="refContentProvider: " + connection
9669                    + " not a ContentProviderConnection";
9670            Slog.w(TAG, msg);
9671            throw new IllegalArgumentException(msg);
9672        }
9673        if (conn == null) {
9674            throw new NullPointerException("connection is null");
9675        }
9676
9677        // Safely retrieve the content provider associated with the connection.
9678        IContentProvider provider;
9679        synchronized (this) {
9680            provider = conn.provider.provider;
9681        }
9682
9683        if (provider == null) {
9684            // Um, yeah, we're way ahead of you.
9685            return;
9686        }
9687
9688        // Make sure the caller is being honest with us.
9689        if (provider.asBinder().pingBinder()) {
9690            // Er, no, still looks good to us.
9691            synchronized (this) {
9692                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9693                        + " says " + conn + " died, but we don't agree");
9694                return;
9695            }
9696        }
9697
9698        // Well look at that!  It's dead!
9699        synchronized (this) {
9700            if (conn.provider.provider != provider) {
9701                // But something changed...  good enough.
9702                return;
9703            }
9704
9705            ProcessRecord proc = conn.provider.proc;
9706            if (proc == null || proc.thread == null) {
9707                // Seems like the process is already cleaned up.
9708                return;
9709            }
9710
9711            // As far as we're concerned, this is just like receiving a
9712            // death notification...  just a bit prematurely.
9713            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9714                    + ") early provider death");
9715            final long ident = Binder.clearCallingIdentity();
9716            try {
9717                appDiedLocked(proc);
9718            } finally {
9719                Binder.restoreCallingIdentity(ident);
9720            }
9721        }
9722    }
9723
9724    @Override
9725    public void appNotRespondingViaProvider(IBinder connection) {
9726        enforceCallingPermission(
9727                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9728
9729        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9730        if (conn == null) {
9731            Slog.w(TAG, "ContentProviderConnection is null");
9732            return;
9733        }
9734
9735        final ProcessRecord host = conn.provider.proc;
9736        if (host == null) {
9737            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9738            return;
9739        }
9740
9741        final long token = Binder.clearCallingIdentity();
9742        try {
9743            appNotResponding(host, null, null, false, "ContentProvider not responding");
9744        } finally {
9745            Binder.restoreCallingIdentity(token);
9746        }
9747    }
9748
9749    public final void installSystemProviders() {
9750        List<ProviderInfo> providers;
9751        synchronized (this) {
9752            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9753            providers = generateApplicationProvidersLocked(app);
9754            if (providers != null) {
9755                for (int i=providers.size()-1; i>=0; i--) {
9756                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9757                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9758                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9759                                + ": not system .apk");
9760                        providers.remove(i);
9761                    }
9762                }
9763            }
9764        }
9765        if (providers != null) {
9766            mSystemThread.installSystemProviders(providers);
9767        }
9768
9769        mCoreSettingsObserver = new CoreSettingsObserver(this);
9770
9771        //mUsageStatsService.monitorPackages();
9772    }
9773
9774    /**
9775     * Allows apps to retrieve the MIME type of a URI.
9776     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9777     * users, then it does not need permission to access the ContentProvider.
9778     * Either, it needs cross-user uri grants.
9779     *
9780     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9781     *
9782     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9783     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9784     */
9785    public String getProviderMimeType(Uri uri, int userId) {
9786        enforceNotIsolatedCaller("getProviderMimeType");
9787        final String name = uri.getAuthority();
9788        int callingUid = Binder.getCallingUid();
9789        int callingPid = Binder.getCallingPid();
9790        long ident = 0;
9791        boolean clearedIdentity = false;
9792        userId = unsafeConvertIncomingUser(userId);
9793        if (canClearIdentity(callingPid, callingUid, userId)) {
9794            clearedIdentity = true;
9795            ident = Binder.clearCallingIdentity();
9796        }
9797        ContentProviderHolder holder = null;
9798        try {
9799            holder = getContentProviderExternalUnchecked(name, null, userId);
9800            if (holder != null) {
9801                return holder.provider.getType(uri);
9802            }
9803        } catch (RemoteException e) {
9804            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9805            return null;
9806        } finally {
9807            // We need to clear the identity to call removeContentProviderExternalUnchecked
9808            if (!clearedIdentity) {
9809                ident = Binder.clearCallingIdentity();
9810            }
9811            try {
9812                if (holder != null) {
9813                    removeContentProviderExternalUnchecked(name, null, userId);
9814                }
9815            } finally {
9816                Binder.restoreCallingIdentity(ident);
9817            }
9818        }
9819
9820        return null;
9821    }
9822
9823    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9824        if (UserHandle.getUserId(callingUid) == userId) {
9825            return true;
9826        }
9827        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9828                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9829                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9830                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9831                return true;
9832        }
9833        return false;
9834    }
9835
9836    // =========================================================
9837    // GLOBAL MANAGEMENT
9838    // =========================================================
9839
9840    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9841            boolean isolated, int isolatedUid) {
9842        String proc = customProcess != null ? customProcess : info.processName;
9843        BatteryStatsImpl.Uid.Proc ps = null;
9844        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9845        int uid = info.uid;
9846        if (isolated) {
9847            if (isolatedUid == 0) {
9848                int userId = UserHandle.getUserId(uid);
9849                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9850                while (true) {
9851                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9852                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9853                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9854                    }
9855                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9856                    mNextIsolatedProcessUid++;
9857                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9858                        // No process for this uid, use it.
9859                        break;
9860                    }
9861                    stepsLeft--;
9862                    if (stepsLeft <= 0) {
9863                        return null;
9864                    }
9865                }
9866            } else {
9867                // Special case for startIsolatedProcess (internal only), where
9868                // the uid of the isolated process is specified by the caller.
9869                uid = isolatedUid;
9870            }
9871        }
9872        return new ProcessRecord(stats, info, proc, uid);
9873    }
9874
9875    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9876            String abiOverride) {
9877        ProcessRecord app;
9878        if (!isolated) {
9879            app = getProcessRecordLocked(info.processName, info.uid, true);
9880        } else {
9881            app = null;
9882        }
9883
9884        if (app == null) {
9885            app = newProcessRecordLocked(info, null, isolated, 0);
9886            mProcessNames.put(info.processName, app.uid, app);
9887            if (isolated) {
9888                mIsolatedProcesses.put(app.uid, app);
9889            }
9890            updateLruProcessLocked(app, false, null);
9891            updateOomAdjLocked();
9892        }
9893
9894        // This package really, really can not be stopped.
9895        try {
9896            AppGlobals.getPackageManager().setPackageStoppedState(
9897                    info.packageName, false, UserHandle.getUserId(app.uid));
9898        } catch (RemoteException e) {
9899        } catch (IllegalArgumentException e) {
9900            Slog.w(TAG, "Failed trying to unstop package "
9901                    + info.packageName + ": " + e);
9902        }
9903
9904        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9905                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9906            app.persistent = true;
9907            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9908        }
9909        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9910            mPersistentStartingProcesses.add(app);
9911            startProcessLocked(app, "added application", app.processName, abiOverride,
9912                    null /* entryPoint */, null /* entryPointArgs */);
9913        }
9914
9915        return app;
9916    }
9917
9918    public void unhandledBack() {
9919        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9920                "unhandledBack()");
9921
9922        synchronized(this) {
9923            final long origId = Binder.clearCallingIdentity();
9924            try {
9925                getFocusedStack().unhandledBackLocked();
9926            } finally {
9927                Binder.restoreCallingIdentity(origId);
9928            }
9929        }
9930    }
9931
9932    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9933        enforceNotIsolatedCaller("openContentUri");
9934        final int userId = UserHandle.getCallingUserId();
9935        String name = uri.getAuthority();
9936        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9937        ParcelFileDescriptor pfd = null;
9938        if (cph != null) {
9939            // We record the binder invoker's uid in thread-local storage before
9940            // going to the content provider to open the file.  Later, in the code
9941            // that handles all permissions checks, we look for this uid and use
9942            // that rather than the Activity Manager's own uid.  The effect is that
9943            // we do the check against the caller's permissions even though it looks
9944            // to the content provider like the Activity Manager itself is making
9945            // the request.
9946            Binder token = new Binder();
9947            sCallerIdentity.set(new Identity(
9948                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9949            try {
9950                pfd = cph.provider.openFile(null, uri, "r", null, token);
9951            } catch (FileNotFoundException e) {
9952                // do nothing; pfd will be returned null
9953            } finally {
9954                // Ensure that whatever happens, we clean up the identity state
9955                sCallerIdentity.remove();
9956            }
9957
9958            // We've got the fd now, so we're done with the provider.
9959            removeContentProviderExternalUnchecked(name, null, userId);
9960        } else {
9961            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9962        }
9963        return pfd;
9964    }
9965
9966    // Actually is sleeping or shutting down or whatever else in the future
9967    // is an inactive state.
9968    public boolean isSleepingOrShuttingDown() {
9969        return isSleeping() || mShuttingDown;
9970    }
9971
9972    public boolean isSleeping() {
9973        return mSleeping;
9974    }
9975
9976    void onWakefulnessChanged(int wakefulness) {
9977        synchronized(this) {
9978            mWakefulness = wakefulness;
9979            updateSleepIfNeededLocked();
9980        }
9981    }
9982
9983    void finishRunningVoiceLocked() {
9984        if (mRunningVoice) {
9985            mRunningVoice = false;
9986            updateSleepIfNeededLocked();
9987        }
9988    }
9989
9990    void updateSleepIfNeededLocked() {
9991        if (mSleeping && !shouldSleepLocked()) {
9992            mSleeping = false;
9993            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9994        } else if (!mSleeping && shouldSleepLocked()) {
9995            mSleeping = true;
9996            mStackSupervisor.goingToSleepLocked();
9997
9998            // Initialize the wake times of all processes.
9999            checkExcessivePowerUsageLocked(false);
10000            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10001            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10002            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10003        }
10004    }
10005
10006    private boolean shouldSleepLocked() {
10007        // Resume applications while running a voice interactor.
10008        if (mRunningVoice) {
10009            return false;
10010        }
10011
10012        switch (mWakefulness) {
10013            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10014            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10015                // If we're interactive but applications are already paused then defer
10016                // resuming them until the lock screen is hidden.
10017                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10018            case PowerManagerInternal.WAKEFULNESS_DOZING:
10019                // If we're dozing then pause applications whenever the lock screen is shown.
10020                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10021            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10022            default:
10023                // If we're asleep then pause applications unconditionally.
10024                return true;
10025        }
10026    }
10027
10028    /** Pokes the task persister. */
10029    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10030        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10031            // Never persist the home stack.
10032            return;
10033        }
10034        mTaskPersister.wakeup(task, flush);
10035    }
10036
10037    /** Notifies all listeners when the task stack has changed. */
10038    void notifyTaskStackChangedLocked() {
10039        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10040        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10041        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10042    }
10043
10044    @Override
10045    public boolean shutdown(int timeout) {
10046        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10047                != PackageManager.PERMISSION_GRANTED) {
10048            throw new SecurityException("Requires permission "
10049                    + android.Manifest.permission.SHUTDOWN);
10050        }
10051
10052        boolean timedout = false;
10053
10054        synchronized(this) {
10055            mShuttingDown = true;
10056            updateEventDispatchingLocked();
10057            timedout = mStackSupervisor.shutdownLocked(timeout);
10058        }
10059
10060        mAppOpsService.shutdown();
10061        if (mUsageStatsService != null) {
10062            mUsageStatsService.prepareShutdown();
10063        }
10064        mBatteryStatsService.shutdown();
10065        synchronized (this) {
10066            mProcessStats.shutdownLocked();
10067            notifyTaskPersisterLocked(null, true);
10068        }
10069
10070        return timedout;
10071    }
10072
10073    public final void activitySlept(IBinder token) {
10074        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10075
10076        final long origId = Binder.clearCallingIdentity();
10077
10078        synchronized (this) {
10079            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10080            if (r != null) {
10081                mStackSupervisor.activitySleptLocked(r);
10082            }
10083        }
10084
10085        Binder.restoreCallingIdentity(origId);
10086    }
10087
10088    private String lockScreenShownToString() {
10089        switch (mLockScreenShown) {
10090            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10091            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10092            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10093            default: return "Unknown=" + mLockScreenShown;
10094        }
10095    }
10096
10097    void logLockScreen(String msg) {
10098        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10099                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10100                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10101                + " mSleeping=" + mSleeping);
10102    }
10103
10104    void startRunningVoiceLocked() {
10105        if (!mRunningVoice) {
10106            mRunningVoice = true;
10107            updateSleepIfNeededLocked();
10108        }
10109    }
10110
10111    private void updateEventDispatchingLocked() {
10112        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10113    }
10114
10115    public void setLockScreenShown(boolean shown) {
10116        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10117                != PackageManager.PERMISSION_GRANTED) {
10118            throw new SecurityException("Requires permission "
10119                    + android.Manifest.permission.DEVICE_POWER);
10120        }
10121
10122        synchronized(this) {
10123            long ident = Binder.clearCallingIdentity();
10124            try {
10125                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10126                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10127                updateSleepIfNeededLocked();
10128            } finally {
10129                Binder.restoreCallingIdentity(ident);
10130            }
10131        }
10132    }
10133
10134    @Override
10135    public void stopAppSwitches() {
10136        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10137                != PackageManager.PERMISSION_GRANTED) {
10138            throw new SecurityException("Requires permission "
10139                    + android.Manifest.permission.STOP_APP_SWITCHES);
10140        }
10141
10142        synchronized(this) {
10143            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10144                    + APP_SWITCH_DELAY_TIME;
10145            mDidAppSwitch = false;
10146            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10147            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10148            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10149        }
10150    }
10151
10152    public void resumeAppSwitches() {
10153        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10154                != PackageManager.PERMISSION_GRANTED) {
10155            throw new SecurityException("Requires permission "
10156                    + android.Manifest.permission.STOP_APP_SWITCHES);
10157        }
10158
10159        synchronized(this) {
10160            // Note that we don't execute any pending app switches... we will
10161            // let those wait until either the timeout, or the next start
10162            // activity request.
10163            mAppSwitchesAllowedTime = 0;
10164        }
10165    }
10166
10167    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10168            int callingPid, int callingUid, String name) {
10169        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10170            return true;
10171        }
10172
10173        int perm = checkComponentPermission(
10174                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10175                sourceUid, -1, true);
10176        if (perm == PackageManager.PERMISSION_GRANTED) {
10177            return true;
10178        }
10179
10180        // If the actual IPC caller is different from the logical source, then
10181        // also see if they are allowed to control app switches.
10182        if (callingUid != -1 && callingUid != sourceUid) {
10183            perm = checkComponentPermission(
10184                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10185                    callingUid, -1, true);
10186            if (perm == PackageManager.PERMISSION_GRANTED) {
10187                return true;
10188            }
10189        }
10190
10191        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10192        return false;
10193    }
10194
10195    public void setDebugApp(String packageName, boolean waitForDebugger,
10196            boolean persistent) {
10197        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10198                "setDebugApp()");
10199
10200        long ident = Binder.clearCallingIdentity();
10201        try {
10202            // Note that this is not really thread safe if there are multiple
10203            // callers into it at the same time, but that's not a situation we
10204            // care about.
10205            if (persistent) {
10206                final ContentResolver resolver = mContext.getContentResolver();
10207                Settings.Global.putString(
10208                    resolver, Settings.Global.DEBUG_APP,
10209                    packageName);
10210                Settings.Global.putInt(
10211                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10212                    waitForDebugger ? 1 : 0);
10213            }
10214
10215            synchronized (this) {
10216                if (!persistent) {
10217                    mOrigDebugApp = mDebugApp;
10218                    mOrigWaitForDebugger = mWaitForDebugger;
10219                }
10220                mDebugApp = packageName;
10221                mWaitForDebugger = waitForDebugger;
10222                mDebugTransient = !persistent;
10223                if (packageName != null) {
10224                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10225                            false, UserHandle.USER_ALL, "set debug app");
10226                }
10227            }
10228        } finally {
10229            Binder.restoreCallingIdentity(ident);
10230        }
10231    }
10232
10233    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10234        synchronized (this) {
10235            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10236            if (!isDebuggable) {
10237                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10238                    throw new SecurityException("Process not debuggable: " + app.packageName);
10239                }
10240            }
10241
10242            mOpenGlTraceApp = processName;
10243        }
10244    }
10245
10246    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10247        synchronized (this) {
10248            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10249            if (!isDebuggable) {
10250                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10251                    throw new SecurityException("Process not debuggable: " + app.packageName);
10252                }
10253            }
10254            mProfileApp = processName;
10255            mProfileFile = profilerInfo.profileFile;
10256            if (mProfileFd != null) {
10257                try {
10258                    mProfileFd.close();
10259                } catch (IOException e) {
10260                }
10261                mProfileFd = null;
10262            }
10263            mProfileFd = profilerInfo.profileFd;
10264            mSamplingInterval = profilerInfo.samplingInterval;
10265            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10266            mProfileType = 0;
10267        }
10268    }
10269
10270    @Override
10271    public void setAlwaysFinish(boolean enabled) {
10272        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10273                "setAlwaysFinish()");
10274
10275        Settings.Global.putInt(
10276                mContext.getContentResolver(),
10277                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10278
10279        synchronized (this) {
10280            mAlwaysFinishActivities = enabled;
10281        }
10282    }
10283
10284    @Override
10285    public void setActivityController(IActivityController controller) {
10286        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10287                "setActivityController()");
10288        synchronized (this) {
10289            mController = controller;
10290            Watchdog.getInstance().setActivityController(controller);
10291        }
10292    }
10293
10294    @Override
10295    public void setUserIsMonkey(boolean userIsMonkey) {
10296        synchronized (this) {
10297            synchronized (mPidsSelfLocked) {
10298                final int callingPid = Binder.getCallingPid();
10299                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10300                if (precessRecord == null) {
10301                    throw new SecurityException("Unknown process: " + callingPid);
10302                }
10303                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10304                    throw new SecurityException("Only an instrumentation process "
10305                            + "with a UiAutomation can call setUserIsMonkey");
10306                }
10307            }
10308            mUserIsMonkey = userIsMonkey;
10309        }
10310    }
10311
10312    @Override
10313    public boolean isUserAMonkey() {
10314        synchronized (this) {
10315            // If there is a controller also implies the user is a monkey.
10316            return (mUserIsMonkey || mController != null);
10317        }
10318    }
10319
10320    public void requestBugReport() {
10321        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10322        SystemProperties.set("ctl.start", "bugreport");
10323    }
10324
10325    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10326        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10327    }
10328
10329    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10330        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10331            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10332        }
10333        return KEY_DISPATCHING_TIMEOUT;
10334    }
10335
10336    @Override
10337    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10338        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10339                != PackageManager.PERMISSION_GRANTED) {
10340            throw new SecurityException("Requires permission "
10341                    + android.Manifest.permission.FILTER_EVENTS);
10342        }
10343        ProcessRecord proc;
10344        long timeout;
10345        synchronized (this) {
10346            synchronized (mPidsSelfLocked) {
10347                proc = mPidsSelfLocked.get(pid);
10348            }
10349            timeout = getInputDispatchingTimeoutLocked(proc);
10350        }
10351
10352        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10353            return -1;
10354        }
10355
10356        return timeout;
10357    }
10358
10359    /**
10360     * Handle input dispatching timeouts.
10361     * Returns whether input dispatching should be aborted or not.
10362     */
10363    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10364            final ActivityRecord activity, final ActivityRecord parent,
10365            final boolean aboveSystem, String reason) {
10366        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10367                != PackageManager.PERMISSION_GRANTED) {
10368            throw new SecurityException("Requires permission "
10369                    + android.Manifest.permission.FILTER_EVENTS);
10370        }
10371
10372        final String annotation;
10373        if (reason == null) {
10374            annotation = "Input dispatching timed out";
10375        } else {
10376            annotation = "Input dispatching timed out (" + reason + ")";
10377        }
10378
10379        if (proc != null) {
10380            synchronized (this) {
10381                if (proc.debugging) {
10382                    return false;
10383                }
10384
10385                if (mDidDexOpt) {
10386                    // Give more time since we were dexopting.
10387                    mDidDexOpt = false;
10388                    return false;
10389                }
10390
10391                if (proc.instrumentationClass != null) {
10392                    Bundle info = new Bundle();
10393                    info.putString("shortMsg", "keyDispatchingTimedOut");
10394                    info.putString("longMsg", annotation);
10395                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10396                    return true;
10397                }
10398            }
10399            mHandler.post(new Runnable() {
10400                @Override
10401                public void run() {
10402                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10403                }
10404            });
10405        }
10406
10407        return true;
10408    }
10409
10410    public Bundle getAssistContextExtras(int requestType) {
10411        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10412                UserHandle.getCallingUserId());
10413        if (pae == null) {
10414            return null;
10415        }
10416        synchronized (pae) {
10417            while (!pae.haveResult) {
10418                try {
10419                    pae.wait();
10420                } catch (InterruptedException e) {
10421                }
10422            }
10423            if (pae.result != null) {
10424                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10425            }
10426        }
10427        synchronized (this) {
10428            mPendingAssistExtras.remove(pae);
10429            mHandler.removeCallbacks(pae);
10430        }
10431        return pae.extras;
10432    }
10433
10434    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10435            int userHandle) {
10436        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10437                "getAssistContextExtras()");
10438        PendingAssistExtras pae;
10439        Bundle extras = new Bundle();
10440        synchronized (this) {
10441            ActivityRecord activity = getFocusedStack().mResumedActivity;
10442            if (activity == null) {
10443                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10444                return null;
10445            }
10446            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10447            if (activity.app == null || activity.app.thread == null) {
10448                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10449                return null;
10450            }
10451            if (activity.app.pid == Binder.getCallingPid()) {
10452                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10453                return null;
10454            }
10455            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10456            try {
10457                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10458                        requestType);
10459                mPendingAssistExtras.add(pae);
10460                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10461            } catch (RemoteException e) {
10462                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10463                return null;
10464            }
10465            return pae;
10466        }
10467    }
10468
10469    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10470        PendingAssistExtras pae = (PendingAssistExtras)token;
10471        synchronized (pae) {
10472            pae.result = extras;
10473            pae.haveResult = true;
10474            pae.notifyAll();
10475            if (pae.intent == null) {
10476                // Caller is just waiting for the result.
10477                return;
10478            }
10479        }
10480
10481        // We are now ready to launch the assist activity.
10482        synchronized (this) {
10483            boolean exists = mPendingAssistExtras.remove(pae);
10484            mHandler.removeCallbacks(pae);
10485            if (!exists) {
10486                // Timed out.
10487                return;
10488            }
10489        }
10490        pae.intent.replaceExtras(extras);
10491        if (pae.hint != null) {
10492            pae.intent.putExtra(pae.hint, true);
10493        }
10494        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10495                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10496                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10497        closeSystemDialogs("assist");
10498        try {
10499            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10500        } catch (ActivityNotFoundException e) {
10501            Slog.w(TAG, "No activity to handle assist action.", e);
10502        }
10503    }
10504
10505    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10506        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10507    }
10508
10509    public void registerProcessObserver(IProcessObserver observer) {
10510        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10511                "registerProcessObserver()");
10512        synchronized (this) {
10513            mProcessObservers.register(observer);
10514        }
10515    }
10516
10517    @Override
10518    public void unregisterProcessObserver(IProcessObserver observer) {
10519        synchronized (this) {
10520            mProcessObservers.unregister(observer);
10521        }
10522    }
10523
10524    @Override
10525    public boolean convertFromTranslucent(IBinder token) {
10526        final long origId = Binder.clearCallingIdentity();
10527        try {
10528            synchronized (this) {
10529                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10530                if (r == null) {
10531                    return false;
10532                }
10533                final boolean translucentChanged = r.changeWindowTranslucency(true);
10534                if (translucentChanged) {
10535                    r.task.stack.releaseBackgroundResources();
10536                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10537                }
10538                mWindowManager.setAppFullscreen(token, true);
10539                return translucentChanged;
10540            }
10541        } finally {
10542            Binder.restoreCallingIdentity(origId);
10543        }
10544    }
10545
10546    @Override
10547    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10548        final long origId = Binder.clearCallingIdentity();
10549        try {
10550            synchronized (this) {
10551                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10552                if (r == null) {
10553                    return false;
10554                }
10555                int index = r.task.mActivities.lastIndexOf(r);
10556                if (index > 0) {
10557                    ActivityRecord under = r.task.mActivities.get(index - 1);
10558                    under.returningOptions = options;
10559                }
10560                final boolean translucentChanged = r.changeWindowTranslucency(false);
10561                if (translucentChanged) {
10562                    r.task.stack.convertToTranslucent(r);
10563                }
10564                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10565                mWindowManager.setAppFullscreen(token, false);
10566                return translucentChanged;
10567            }
10568        } finally {
10569            Binder.restoreCallingIdentity(origId);
10570        }
10571    }
10572
10573    @Override
10574    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10575        final long origId = Binder.clearCallingIdentity();
10576        try {
10577            synchronized (this) {
10578                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10579                if (r != null) {
10580                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10581                }
10582            }
10583            return false;
10584        } finally {
10585            Binder.restoreCallingIdentity(origId);
10586        }
10587    }
10588
10589    @Override
10590    public boolean isBackgroundVisibleBehind(IBinder token) {
10591        final long origId = Binder.clearCallingIdentity();
10592        try {
10593            synchronized (this) {
10594                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10595                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10596                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10597                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10598                return visible;
10599            }
10600        } finally {
10601            Binder.restoreCallingIdentity(origId);
10602        }
10603    }
10604
10605    @Override
10606    public ActivityOptions getActivityOptions(IBinder token) {
10607        final long origId = Binder.clearCallingIdentity();
10608        try {
10609            synchronized (this) {
10610                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10611                if (r != null) {
10612                    final ActivityOptions activityOptions = r.pendingOptions;
10613                    r.pendingOptions = null;
10614                    return activityOptions;
10615                }
10616                return null;
10617            }
10618        } finally {
10619            Binder.restoreCallingIdentity(origId);
10620        }
10621    }
10622
10623    @Override
10624    public void setImmersive(IBinder token, boolean immersive) {
10625        synchronized(this) {
10626            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10627            if (r == null) {
10628                throw new IllegalArgumentException();
10629            }
10630            r.immersive = immersive;
10631
10632            // update associated state if we're frontmost
10633            if (r == mFocusedActivity) {
10634                if (DEBUG_IMMERSIVE) {
10635                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10636                }
10637                applyUpdateLockStateLocked(r);
10638            }
10639        }
10640    }
10641
10642    @Override
10643    public boolean isImmersive(IBinder token) {
10644        synchronized (this) {
10645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10646            if (r == null) {
10647                throw new IllegalArgumentException();
10648            }
10649            return r.immersive;
10650        }
10651    }
10652
10653    public boolean isTopActivityImmersive() {
10654        enforceNotIsolatedCaller("startActivity");
10655        synchronized (this) {
10656            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10657            return (r != null) ? r.immersive : false;
10658        }
10659    }
10660
10661    @Override
10662    public boolean isTopOfTask(IBinder token) {
10663        synchronized (this) {
10664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10665            if (r == null) {
10666                throw new IllegalArgumentException();
10667            }
10668            return r.task.getTopActivity() == r;
10669        }
10670    }
10671
10672    public final void enterSafeMode() {
10673        synchronized(this) {
10674            // It only makes sense to do this before the system is ready
10675            // and started launching other packages.
10676            if (!mSystemReady) {
10677                try {
10678                    AppGlobals.getPackageManager().enterSafeMode();
10679                } catch (RemoteException e) {
10680                }
10681            }
10682
10683            mSafeMode = true;
10684        }
10685    }
10686
10687    public final void showSafeModeOverlay() {
10688        View v = LayoutInflater.from(mContext).inflate(
10689                com.android.internal.R.layout.safe_mode, null);
10690        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10691        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10692        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10693        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10694        lp.gravity = Gravity.BOTTOM | Gravity.START;
10695        lp.format = v.getBackground().getOpacity();
10696        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10697                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10698        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10699        ((WindowManager)mContext.getSystemService(
10700                Context.WINDOW_SERVICE)).addView(v, lp);
10701    }
10702
10703    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10704        if (!(sender instanceof PendingIntentRecord)) {
10705            return;
10706        }
10707        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10708        synchronized (stats) {
10709            if (mBatteryStatsService.isOnBattery()) {
10710                mBatteryStatsService.enforceCallingPermission();
10711                PendingIntentRecord rec = (PendingIntentRecord)sender;
10712                int MY_UID = Binder.getCallingUid();
10713                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10714                BatteryStatsImpl.Uid.Pkg pkg =
10715                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10716                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10717                pkg.incWakeupsLocked();
10718            }
10719        }
10720    }
10721
10722    public boolean killPids(int[] pids, String pReason, boolean secure) {
10723        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10724            throw new SecurityException("killPids only available to the system");
10725        }
10726        String reason = (pReason == null) ? "Unknown" : pReason;
10727        // XXX Note: don't acquire main activity lock here, because the window
10728        // manager calls in with its locks held.
10729
10730        boolean killed = false;
10731        synchronized (mPidsSelfLocked) {
10732            int[] types = new int[pids.length];
10733            int worstType = 0;
10734            for (int i=0; i<pids.length; i++) {
10735                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10736                if (proc != null) {
10737                    int type = proc.setAdj;
10738                    types[i] = type;
10739                    if (type > worstType) {
10740                        worstType = type;
10741                    }
10742                }
10743            }
10744
10745            // If the worst oom_adj is somewhere in the cached proc LRU range,
10746            // then constrain it so we will kill all cached procs.
10747            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10748                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10749                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10750            }
10751
10752            // If this is not a secure call, don't let it kill processes that
10753            // are important.
10754            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10755                worstType = ProcessList.SERVICE_ADJ;
10756            }
10757
10758            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10759            for (int i=0; i<pids.length; i++) {
10760                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10761                if (proc == null) {
10762                    continue;
10763                }
10764                int adj = proc.setAdj;
10765                if (adj >= worstType && !proc.killedByAm) {
10766                    proc.kill(reason, true);
10767                    killed = true;
10768                }
10769            }
10770        }
10771        return killed;
10772    }
10773
10774    @Override
10775    public void killUid(int uid, String reason) {
10776        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10777            throw new SecurityException("killUid only available to the system");
10778        }
10779        synchronized (this) {
10780            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10781                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10782                    reason != null ? reason : "kill uid");
10783        }
10784    }
10785
10786    @Override
10787    public boolean killProcessesBelowForeground(String reason) {
10788        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10789            throw new SecurityException("killProcessesBelowForeground() only available to system");
10790        }
10791
10792        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10793    }
10794
10795    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10797            throw new SecurityException("killProcessesBelowAdj() only available to system");
10798        }
10799
10800        boolean killed = false;
10801        synchronized (mPidsSelfLocked) {
10802            final int size = mPidsSelfLocked.size();
10803            for (int i = 0; i < size; i++) {
10804                final int pid = mPidsSelfLocked.keyAt(i);
10805                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10806                if (proc == null) continue;
10807
10808                final int adj = proc.setAdj;
10809                if (adj > belowAdj && !proc.killedByAm) {
10810                    proc.kill(reason, true);
10811                    killed = true;
10812                }
10813            }
10814        }
10815        return killed;
10816    }
10817
10818    @Override
10819    public void hang(final IBinder who, boolean allowRestart) {
10820        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10821                != PackageManager.PERMISSION_GRANTED) {
10822            throw new SecurityException("Requires permission "
10823                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10824        }
10825
10826        final IBinder.DeathRecipient death = new DeathRecipient() {
10827            @Override
10828            public void binderDied() {
10829                synchronized (this) {
10830                    notifyAll();
10831                }
10832            }
10833        };
10834
10835        try {
10836            who.linkToDeath(death, 0);
10837        } catch (RemoteException e) {
10838            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10839            return;
10840        }
10841
10842        synchronized (this) {
10843            Watchdog.getInstance().setAllowRestart(allowRestart);
10844            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10845            synchronized (death) {
10846                while (who.isBinderAlive()) {
10847                    try {
10848                        death.wait();
10849                    } catch (InterruptedException e) {
10850                    }
10851                }
10852            }
10853            Watchdog.getInstance().setAllowRestart(true);
10854        }
10855    }
10856
10857    @Override
10858    public void restart() {
10859        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10860                != PackageManager.PERMISSION_GRANTED) {
10861            throw new SecurityException("Requires permission "
10862                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10863        }
10864
10865        Log.i(TAG, "Sending shutdown broadcast...");
10866
10867        BroadcastReceiver br = new BroadcastReceiver() {
10868            @Override public void onReceive(Context context, Intent intent) {
10869                // Now the broadcast is done, finish up the low-level shutdown.
10870                Log.i(TAG, "Shutting down activity manager...");
10871                shutdown(10000);
10872                Log.i(TAG, "Shutdown complete, restarting!");
10873                Process.killProcess(Process.myPid());
10874                System.exit(10);
10875            }
10876        };
10877
10878        // First send the high-level shut down broadcast.
10879        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10880        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10881        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10882        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10883        mContext.sendOrderedBroadcastAsUser(intent,
10884                UserHandle.ALL, null, br, mHandler, 0, null, null);
10885        */
10886        br.onReceive(mContext, intent);
10887    }
10888
10889    private long getLowRamTimeSinceIdle(long now) {
10890        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10891    }
10892
10893    @Override
10894    public void performIdleMaintenance() {
10895        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10896                != PackageManager.PERMISSION_GRANTED) {
10897            throw new SecurityException("Requires permission "
10898                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10899        }
10900
10901        synchronized (this) {
10902            final long now = SystemClock.uptimeMillis();
10903            final long timeSinceLastIdle = now - mLastIdleTime;
10904            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10905            mLastIdleTime = now;
10906            mLowRamTimeSinceLastIdle = 0;
10907            if (mLowRamStartTime != 0) {
10908                mLowRamStartTime = now;
10909            }
10910
10911            StringBuilder sb = new StringBuilder(128);
10912            sb.append("Idle maintenance over ");
10913            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10914            sb.append(" low RAM for ");
10915            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10916            Slog.i(TAG, sb.toString());
10917
10918            // If at least 1/3 of our time since the last idle period has been spent
10919            // with RAM low, then we want to kill processes.
10920            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10921
10922            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10923                ProcessRecord proc = mLruProcesses.get(i);
10924                if (proc.notCachedSinceIdle) {
10925                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10926                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10927                        if (doKilling && proc.initialIdlePss != 0
10928                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10929                            sb = new StringBuilder(128);
10930                            sb.append("Kill");
10931                            sb.append(proc.processName);
10932                            sb.append(" in idle maint: pss=");
10933                            sb.append(proc.lastPss);
10934                            sb.append(", initialPss=");
10935                            sb.append(proc.initialIdlePss);
10936                            sb.append(", period=");
10937                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10938                            sb.append(", lowRamPeriod=");
10939                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10940                            Slog.wtfQuiet(TAG, sb.toString());
10941                            proc.kill("idle maint (pss " + proc.lastPss
10942                                    + " from " + proc.initialIdlePss + ")", true);
10943                        }
10944                    }
10945                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10946                    proc.notCachedSinceIdle = true;
10947                    proc.initialIdlePss = 0;
10948                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10949                            mTestPssMode, isSleeping(), now);
10950                }
10951            }
10952
10953            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10954            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10955        }
10956    }
10957
10958    private void retrieveSettings() {
10959        final ContentResolver resolver = mContext.getContentResolver();
10960        String debugApp = Settings.Global.getString(
10961            resolver, Settings.Global.DEBUG_APP);
10962        boolean waitForDebugger = Settings.Global.getInt(
10963            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10964        boolean alwaysFinishActivities = Settings.Global.getInt(
10965            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10966        boolean forceRtl = Settings.Global.getInt(
10967                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10968        // Transfer any global setting for forcing RTL layout, into a System Property
10969        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10970
10971        Configuration configuration = new Configuration();
10972        Settings.System.getConfiguration(resolver, configuration);
10973        if (forceRtl) {
10974            // This will take care of setting the correct layout direction flags
10975            configuration.setLayoutDirection(configuration.locale);
10976        }
10977
10978        synchronized (this) {
10979            mDebugApp = mOrigDebugApp = debugApp;
10980            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10981            mAlwaysFinishActivities = alwaysFinishActivities;
10982            // This happens before any activities are started, so we can
10983            // change mConfiguration in-place.
10984            updateConfigurationLocked(configuration, null, false, true);
10985            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10986        }
10987    }
10988
10989    /** Loads resources after the current configuration has been set. */
10990    private void loadResourcesOnSystemReady() {
10991        final Resources res = mContext.getResources();
10992        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10993        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10994        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10995    }
10996
10997    public boolean testIsSystemReady() {
10998        // no need to synchronize(this) just to read & return the value
10999        return mSystemReady;
11000    }
11001
11002    private static File getCalledPreBootReceiversFile() {
11003        File dataDir = Environment.getDataDirectory();
11004        File systemDir = new File(dataDir, "system");
11005        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11006        return fname;
11007    }
11008
11009    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11010        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11011        File file = getCalledPreBootReceiversFile();
11012        FileInputStream fis = null;
11013        try {
11014            fis = new FileInputStream(file);
11015            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11016            int fvers = dis.readInt();
11017            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11018                String vers = dis.readUTF();
11019                String codename = dis.readUTF();
11020                String build = dis.readUTF();
11021                if (android.os.Build.VERSION.RELEASE.equals(vers)
11022                        && android.os.Build.VERSION.CODENAME.equals(codename)
11023                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11024                    int num = dis.readInt();
11025                    while (num > 0) {
11026                        num--;
11027                        String pkg = dis.readUTF();
11028                        String cls = dis.readUTF();
11029                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11030                    }
11031                }
11032            }
11033        } catch (FileNotFoundException e) {
11034        } catch (IOException e) {
11035            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11036        } finally {
11037            if (fis != null) {
11038                try {
11039                    fis.close();
11040                } catch (IOException e) {
11041                }
11042            }
11043        }
11044        return lastDoneReceivers;
11045    }
11046
11047    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11048        File file = getCalledPreBootReceiversFile();
11049        FileOutputStream fos = null;
11050        DataOutputStream dos = null;
11051        try {
11052            fos = new FileOutputStream(file);
11053            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11054            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11055            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11056            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11057            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11058            dos.writeInt(list.size());
11059            for (int i=0; i<list.size(); i++) {
11060                dos.writeUTF(list.get(i).getPackageName());
11061                dos.writeUTF(list.get(i).getClassName());
11062            }
11063        } catch (IOException e) {
11064            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11065            file.delete();
11066        } finally {
11067            FileUtils.sync(fos);
11068            if (dos != null) {
11069                try {
11070                    dos.close();
11071                } catch (IOException e) {
11072                    // TODO Auto-generated catch block
11073                    e.printStackTrace();
11074                }
11075            }
11076        }
11077    }
11078
11079    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11080            ArrayList<ComponentName> doneReceivers, int userId) {
11081        boolean waitingUpdate = false;
11082        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11083        List<ResolveInfo> ris = null;
11084        try {
11085            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11086                    intent, null, 0, userId);
11087        } catch (RemoteException e) {
11088        }
11089        if (ris != null) {
11090            for (int i=ris.size()-1; i>=0; i--) {
11091                if ((ris.get(i).activityInfo.applicationInfo.flags
11092                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11093                    ris.remove(i);
11094                }
11095            }
11096            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11097
11098            // For User 0, load the version number. When delivering to a new user, deliver
11099            // to all receivers.
11100            if (userId == UserHandle.USER_OWNER) {
11101                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11102                for (int i=0; i<ris.size(); i++) {
11103                    ActivityInfo ai = ris.get(i).activityInfo;
11104                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11105                    if (lastDoneReceivers.contains(comp)) {
11106                        // We already did the pre boot receiver for this app with the current
11107                        // platform version, so don't do it again...
11108                        ris.remove(i);
11109                        i--;
11110                        // ...however, do keep it as one that has been done, so we don't
11111                        // forget about it when rewriting the file of last done receivers.
11112                        doneReceivers.add(comp);
11113                    }
11114                }
11115            }
11116
11117            // If primary user, send broadcast to all available users, else just to userId
11118            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11119                    : new int[] { userId };
11120            for (int i = 0; i < ris.size(); i++) {
11121                ActivityInfo ai = ris.get(i).activityInfo;
11122                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11123                doneReceivers.add(comp);
11124                intent.setComponent(comp);
11125                for (int j=0; j<users.length; j++) {
11126                    IIntentReceiver finisher = null;
11127                    // On last receiver and user, set up a completion callback
11128                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11129                        finisher = new IIntentReceiver.Stub() {
11130                            public void performReceive(Intent intent, int resultCode,
11131                                    String data, Bundle extras, boolean ordered,
11132                                    boolean sticky, int sendingUser) {
11133                                // The raw IIntentReceiver interface is called
11134                                // with the AM lock held, so redispatch to
11135                                // execute our code without the lock.
11136                                mHandler.post(onFinishCallback);
11137                            }
11138                        };
11139                    }
11140                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11141                            + " for user " + users[j]);
11142                    broadcastIntentLocked(null, null, intent, null, finisher,
11143                            0, null, null, null, AppOpsManager.OP_NONE,
11144                            true, false, MY_PID, Process.SYSTEM_UID,
11145                            users[j]);
11146                    if (finisher != null) {
11147                        waitingUpdate = true;
11148                    }
11149                }
11150            }
11151        }
11152
11153        return waitingUpdate;
11154    }
11155
11156    public void systemReady(final Runnable goingCallback) {
11157        synchronized(this) {
11158            if (mSystemReady) {
11159                // If we're done calling all the receivers, run the next "boot phase" passed in
11160                // by the SystemServer
11161                if (goingCallback != null) {
11162                    goingCallback.run();
11163                }
11164                return;
11165            }
11166
11167            // Make sure we have the current profile info, since it is needed for
11168            // security checks.
11169            updateCurrentProfileIdsLocked();
11170
11171            if (mRecentTasks == null) {
11172                mRecentTasks = mTaskPersister.restoreTasksLocked();
11173                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11174                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11175                mTaskPersister.startPersisting();
11176            }
11177
11178            // Check to see if there are any update receivers to run.
11179            if (!mDidUpdate) {
11180                if (mWaitingUpdate) {
11181                    return;
11182                }
11183                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11184                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11185                    public void run() {
11186                        synchronized (ActivityManagerService.this) {
11187                            mDidUpdate = true;
11188                        }
11189                        writeLastDonePreBootReceivers(doneReceivers);
11190                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11191                                false);
11192                        systemReady(goingCallback);
11193                    }
11194                }, doneReceivers, UserHandle.USER_OWNER);
11195
11196                if (mWaitingUpdate) {
11197                    return;
11198                }
11199                mDidUpdate = true;
11200            }
11201
11202            mAppOpsService.systemReady();
11203            mSystemReady = true;
11204        }
11205
11206        ArrayList<ProcessRecord> procsToKill = null;
11207        synchronized(mPidsSelfLocked) {
11208            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11209                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11210                if (!isAllowedWhileBooting(proc.info)){
11211                    if (procsToKill == null) {
11212                        procsToKill = new ArrayList<ProcessRecord>();
11213                    }
11214                    procsToKill.add(proc);
11215                }
11216            }
11217        }
11218
11219        synchronized(this) {
11220            if (procsToKill != null) {
11221                for (int i=procsToKill.size()-1; i>=0; i--) {
11222                    ProcessRecord proc = procsToKill.get(i);
11223                    Slog.i(TAG, "Removing system update proc: " + proc);
11224                    removeProcessLocked(proc, true, false, "system update done");
11225                }
11226            }
11227
11228            // Now that we have cleaned up any update processes, we
11229            // are ready to start launching real processes and know that
11230            // we won't trample on them any more.
11231            mProcessesReady = true;
11232        }
11233
11234        Slog.i(TAG, "System now ready");
11235        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11236            SystemClock.uptimeMillis());
11237
11238        synchronized(this) {
11239            // Make sure we have no pre-ready processes sitting around.
11240
11241            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11242                ResolveInfo ri = mContext.getPackageManager()
11243                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11244                                STOCK_PM_FLAGS);
11245                CharSequence errorMsg = null;
11246                if (ri != null) {
11247                    ActivityInfo ai = ri.activityInfo;
11248                    ApplicationInfo app = ai.applicationInfo;
11249                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11250                        mTopAction = Intent.ACTION_FACTORY_TEST;
11251                        mTopData = null;
11252                        mTopComponent = new ComponentName(app.packageName,
11253                                ai.name);
11254                    } else {
11255                        errorMsg = mContext.getResources().getText(
11256                                com.android.internal.R.string.factorytest_not_system);
11257                    }
11258                } else {
11259                    errorMsg = mContext.getResources().getText(
11260                            com.android.internal.R.string.factorytest_no_action);
11261                }
11262                if (errorMsg != null) {
11263                    mTopAction = null;
11264                    mTopData = null;
11265                    mTopComponent = null;
11266                    Message msg = Message.obtain();
11267                    msg.what = SHOW_FACTORY_ERROR_MSG;
11268                    msg.getData().putCharSequence("msg", errorMsg);
11269                    mHandler.sendMessage(msg);
11270                }
11271            }
11272        }
11273
11274        retrieveSettings();
11275        loadResourcesOnSystemReady();
11276
11277        synchronized (this) {
11278            readGrantedUriPermissionsLocked();
11279        }
11280
11281        if (goingCallback != null) goingCallback.run();
11282
11283        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11284                Integer.toString(mCurrentUserId), mCurrentUserId);
11285        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11286                Integer.toString(mCurrentUserId), mCurrentUserId);
11287        mSystemServiceManager.startUser(mCurrentUserId);
11288
11289        synchronized (this) {
11290            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11291                try {
11292                    List apps = AppGlobals.getPackageManager().
11293                        getPersistentApplications(STOCK_PM_FLAGS);
11294                    if (apps != null) {
11295                        int N = apps.size();
11296                        int i;
11297                        for (i=0; i<N; i++) {
11298                            ApplicationInfo info
11299                                = (ApplicationInfo)apps.get(i);
11300                            if (info != null &&
11301                                    !info.packageName.equals("android")) {
11302                                addAppLocked(info, false, null /* ABI override */);
11303                            }
11304                        }
11305                    }
11306                } catch (RemoteException ex) {
11307                    // pm is in same process, this will never happen.
11308                }
11309            }
11310
11311            // Start up initial activity.
11312            mBooting = true;
11313            startHomeActivityLocked(mCurrentUserId);
11314
11315            try {
11316                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11317                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11318                            + " data partition or your device will be unstable.");
11319                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11320                }
11321            } catch (RemoteException e) {
11322            }
11323
11324            if (!Build.isFingerprintConsistent()) {
11325                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11326                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11327            }
11328
11329            long ident = Binder.clearCallingIdentity();
11330            try {
11331                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11332                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11333                        | Intent.FLAG_RECEIVER_FOREGROUND);
11334                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11335                broadcastIntentLocked(null, null, intent,
11336                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11337                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11338                intent = new Intent(Intent.ACTION_USER_STARTING);
11339                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11340                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11341                broadcastIntentLocked(null, null, intent,
11342                        null, new IIntentReceiver.Stub() {
11343                            @Override
11344                            public void performReceive(Intent intent, int resultCode, String data,
11345                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11346                                    throws RemoteException {
11347                            }
11348                        }, 0, null, null,
11349                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11350                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11351            } catch (Throwable t) {
11352                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11353            } finally {
11354                Binder.restoreCallingIdentity(ident);
11355            }
11356            mStackSupervisor.resumeTopActivitiesLocked();
11357            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11358        }
11359    }
11360
11361    private boolean makeAppCrashingLocked(ProcessRecord app,
11362            String shortMsg, String longMsg, String stackTrace) {
11363        app.crashing = true;
11364        app.crashingReport = generateProcessError(app,
11365                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11366        startAppProblemLocked(app);
11367        app.stopFreezingAllLocked();
11368        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11369    }
11370
11371    private void makeAppNotRespondingLocked(ProcessRecord app,
11372            String activity, String shortMsg, String longMsg) {
11373        app.notResponding = true;
11374        app.notRespondingReport = generateProcessError(app,
11375                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11376                activity, shortMsg, longMsg, null);
11377        startAppProblemLocked(app);
11378        app.stopFreezingAllLocked();
11379    }
11380
11381    /**
11382     * Generate a process error record, suitable for attachment to a ProcessRecord.
11383     *
11384     * @param app The ProcessRecord in which the error occurred.
11385     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11386     *                      ActivityManager.AppErrorStateInfo
11387     * @param activity The activity associated with the crash, if known.
11388     * @param shortMsg Short message describing the crash.
11389     * @param longMsg Long message describing the crash.
11390     * @param stackTrace Full crash stack trace, may be null.
11391     *
11392     * @return Returns a fully-formed AppErrorStateInfo record.
11393     */
11394    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11395            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11396        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11397
11398        report.condition = condition;
11399        report.processName = app.processName;
11400        report.pid = app.pid;
11401        report.uid = app.info.uid;
11402        report.tag = activity;
11403        report.shortMsg = shortMsg;
11404        report.longMsg = longMsg;
11405        report.stackTrace = stackTrace;
11406
11407        return report;
11408    }
11409
11410    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11411        synchronized (this) {
11412            app.crashing = false;
11413            app.crashingReport = null;
11414            app.notResponding = false;
11415            app.notRespondingReport = null;
11416            if (app.anrDialog == fromDialog) {
11417                app.anrDialog = null;
11418            }
11419            if (app.waitDialog == fromDialog) {
11420                app.waitDialog = null;
11421            }
11422            if (app.pid > 0 && app.pid != MY_PID) {
11423                handleAppCrashLocked(app, null, null, null);
11424                app.kill("user request after error", true);
11425            }
11426        }
11427    }
11428
11429    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11430            String stackTrace) {
11431        long now = SystemClock.uptimeMillis();
11432
11433        Long crashTime;
11434        if (!app.isolated) {
11435            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11436        } else {
11437            crashTime = null;
11438        }
11439        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11440            // This process loses!
11441            Slog.w(TAG, "Process " + app.info.processName
11442                    + " has crashed too many times: killing!");
11443            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11444                    app.userId, app.info.processName, app.uid);
11445            mStackSupervisor.handleAppCrashLocked(app);
11446            if (!app.persistent) {
11447                // We don't want to start this process again until the user
11448                // explicitly does so...  but for persistent process, we really
11449                // need to keep it running.  If a persistent process is actually
11450                // repeatedly crashing, then badness for everyone.
11451                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11452                        app.info.processName);
11453                if (!app.isolated) {
11454                    // XXX We don't have a way to mark isolated processes
11455                    // as bad, since they don't have a peristent identity.
11456                    mBadProcesses.put(app.info.processName, app.uid,
11457                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11458                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11459                }
11460                app.bad = true;
11461                app.removed = true;
11462                // Don't let services in this process be restarted and potentially
11463                // annoy the user repeatedly.  Unless it is persistent, since those
11464                // processes run critical code.
11465                removeProcessLocked(app, false, false, "crash");
11466                mStackSupervisor.resumeTopActivitiesLocked();
11467                return false;
11468            }
11469            mStackSupervisor.resumeTopActivitiesLocked();
11470        } else {
11471            mStackSupervisor.finishTopRunningActivityLocked(app);
11472        }
11473
11474        // Bump up the crash count of any services currently running in the proc.
11475        for (int i=app.services.size()-1; i>=0; i--) {
11476            // Any services running in the application need to be placed
11477            // back in the pending list.
11478            ServiceRecord sr = app.services.valueAt(i);
11479            sr.crashCount++;
11480        }
11481
11482        // If the crashing process is what we consider to be the "home process" and it has been
11483        // replaced by a third-party app, clear the package preferred activities from packages
11484        // with a home activity running in the process to prevent a repeatedly crashing app
11485        // from blocking the user to manually clear the list.
11486        final ArrayList<ActivityRecord> activities = app.activities;
11487        if (app == mHomeProcess && activities.size() > 0
11488                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11489            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11490                final ActivityRecord r = activities.get(activityNdx);
11491                if (r.isHomeActivity()) {
11492                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11493                    try {
11494                        ActivityThread.getPackageManager()
11495                                .clearPackagePreferredActivities(r.packageName);
11496                    } catch (RemoteException c) {
11497                        // pm is in same process, this will never happen.
11498                    }
11499                }
11500            }
11501        }
11502
11503        if (!app.isolated) {
11504            // XXX Can't keep track of crash times for isolated processes,
11505            // because they don't have a perisistent identity.
11506            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11507        }
11508
11509        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11510        return true;
11511    }
11512
11513    void startAppProblemLocked(ProcessRecord app) {
11514        // If this app is not running under the current user, then we
11515        // can't give it a report button because that would require
11516        // launching the report UI under a different user.
11517        app.errorReportReceiver = null;
11518
11519        for (int userId : mCurrentProfileIds) {
11520            if (app.userId == userId) {
11521                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11522                        mContext, app.info.packageName, app.info.flags);
11523            }
11524        }
11525        skipCurrentReceiverLocked(app);
11526    }
11527
11528    void skipCurrentReceiverLocked(ProcessRecord app) {
11529        for (BroadcastQueue queue : mBroadcastQueues) {
11530            queue.skipCurrentReceiverLocked(app);
11531        }
11532    }
11533
11534    /**
11535     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11536     * The application process will exit immediately after this call returns.
11537     * @param app object of the crashing app, null for the system server
11538     * @param crashInfo describing the exception
11539     */
11540    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11541        ProcessRecord r = findAppProcess(app, "Crash");
11542        final String processName = app == null ? "system_server"
11543                : (r == null ? "unknown" : r.processName);
11544
11545        handleApplicationCrashInner("crash", r, processName, crashInfo);
11546    }
11547
11548    /* Native crash reporting uses this inner version because it needs to be somewhat
11549     * decoupled from the AM-managed cleanup lifecycle
11550     */
11551    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11552            ApplicationErrorReport.CrashInfo crashInfo) {
11553        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11554                UserHandle.getUserId(Binder.getCallingUid()), processName,
11555                r == null ? -1 : r.info.flags,
11556                crashInfo.exceptionClassName,
11557                crashInfo.exceptionMessage,
11558                crashInfo.throwFileName,
11559                crashInfo.throwLineNumber);
11560
11561        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11562
11563        crashApplication(r, crashInfo);
11564    }
11565
11566    public void handleApplicationStrictModeViolation(
11567            IBinder app,
11568            int violationMask,
11569            StrictMode.ViolationInfo info) {
11570        ProcessRecord r = findAppProcess(app, "StrictMode");
11571        if (r == null) {
11572            return;
11573        }
11574
11575        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11576            Integer stackFingerprint = info.hashCode();
11577            boolean logIt = true;
11578            synchronized (mAlreadyLoggedViolatedStacks) {
11579                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11580                    logIt = false;
11581                    // TODO: sub-sample into EventLog for these, with
11582                    // the info.durationMillis?  Then we'd get
11583                    // the relative pain numbers, without logging all
11584                    // the stack traces repeatedly.  We'd want to do
11585                    // likewise in the client code, which also does
11586                    // dup suppression, before the Binder call.
11587                } else {
11588                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11589                        mAlreadyLoggedViolatedStacks.clear();
11590                    }
11591                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11592                }
11593            }
11594            if (logIt) {
11595                logStrictModeViolationToDropBox(r, info);
11596            }
11597        }
11598
11599        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11600            AppErrorResult result = new AppErrorResult();
11601            synchronized (this) {
11602                final long origId = Binder.clearCallingIdentity();
11603
11604                Message msg = Message.obtain();
11605                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11606                HashMap<String, Object> data = new HashMap<String, Object>();
11607                data.put("result", result);
11608                data.put("app", r);
11609                data.put("violationMask", violationMask);
11610                data.put("info", info);
11611                msg.obj = data;
11612                mHandler.sendMessage(msg);
11613
11614                Binder.restoreCallingIdentity(origId);
11615            }
11616            int res = result.get();
11617            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11618        }
11619    }
11620
11621    // Depending on the policy in effect, there could be a bunch of
11622    // these in quick succession so we try to batch these together to
11623    // minimize disk writes, number of dropbox entries, and maximize
11624    // compression, by having more fewer, larger records.
11625    private void logStrictModeViolationToDropBox(
11626            ProcessRecord process,
11627            StrictMode.ViolationInfo info) {
11628        if (info == null) {
11629            return;
11630        }
11631        final boolean isSystemApp = process == null ||
11632                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11633                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11634        final String processName = process == null ? "unknown" : process.processName;
11635        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11636        final DropBoxManager dbox = (DropBoxManager)
11637                mContext.getSystemService(Context.DROPBOX_SERVICE);
11638
11639        // Exit early if the dropbox isn't configured to accept this report type.
11640        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11641
11642        boolean bufferWasEmpty;
11643        boolean needsFlush;
11644        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11645        synchronized (sb) {
11646            bufferWasEmpty = sb.length() == 0;
11647            appendDropBoxProcessHeaders(process, processName, sb);
11648            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11649            sb.append("System-App: ").append(isSystemApp).append("\n");
11650            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11651            if (info.violationNumThisLoop != 0) {
11652                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11653            }
11654            if (info.numAnimationsRunning != 0) {
11655                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11656            }
11657            if (info.broadcastIntentAction != null) {
11658                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11659            }
11660            if (info.durationMillis != -1) {
11661                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11662            }
11663            if (info.numInstances != -1) {
11664                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11665            }
11666            if (info.tags != null) {
11667                for (String tag : info.tags) {
11668                    sb.append("Span-Tag: ").append(tag).append("\n");
11669                }
11670            }
11671            sb.append("\n");
11672            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11673                sb.append(info.crashInfo.stackTrace);
11674            }
11675            sb.append("\n");
11676
11677            // Only buffer up to ~64k.  Various logging bits truncate
11678            // things at 128k.
11679            needsFlush = (sb.length() > 64 * 1024);
11680        }
11681
11682        // Flush immediately if the buffer's grown too large, or this
11683        // is a non-system app.  Non-system apps are isolated with a
11684        // different tag & policy and not batched.
11685        //
11686        // Batching is useful during internal testing with
11687        // StrictMode settings turned up high.  Without batching,
11688        // thousands of separate files could be created on boot.
11689        if (!isSystemApp || needsFlush) {
11690            new Thread("Error dump: " + dropboxTag) {
11691                @Override
11692                public void run() {
11693                    String report;
11694                    synchronized (sb) {
11695                        report = sb.toString();
11696                        sb.delete(0, sb.length());
11697                        sb.trimToSize();
11698                    }
11699                    if (report.length() != 0) {
11700                        dbox.addText(dropboxTag, report);
11701                    }
11702                }
11703            }.start();
11704            return;
11705        }
11706
11707        // System app batching:
11708        if (!bufferWasEmpty) {
11709            // An existing dropbox-writing thread is outstanding, so
11710            // we don't need to start it up.  The existing thread will
11711            // catch the buffer appends we just did.
11712            return;
11713        }
11714
11715        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11716        // (After this point, we shouldn't access AMS internal data structures.)
11717        new Thread("Error dump: " + dropboxTag) {
11718            @Override
11719            public void run() {
11720                // 5 second sleep to let stacks arrive and be batched together
11721                try {
11722                    Thread.sleep(5000);  // 5 seconds
11723                } catch (InterruptedException e) {}
11724
11725                String errorReport;
11726                synchronized (mStrictModeBuffer) {
11727                    errorReport = mStrictModeBuffer.toString();
11728                    if (errorReport.length() == 0) {
11729                        return;
11730                    }
11731                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11732                    mStrictModeBuffer.trimToSize();
11733                }
11734                dbox.addText(dropboxTag, errorReport);
11735            }
11736        }.start();
11737    }
11738
11739    /**
11740     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11741     * @param app object of the crashing app, null for the system server
11742     * @param tag reported by the caller
11743     * @param system whether this wtf is coming from the system
11744     * @param crashInfo describing the context of the error
11745     * @return true if the process should exit immediately (WTF is fatal)
11746     */
11747    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11748            final ApplicationErrorReport.CrashInfo crashInfo) {
11749        final int callingUid = Binder.getCallingUid();
11750        final int callingPid = Binder.getCallingPid();
11751
11752        if (system) {
11753            // If this is coming from the system, we could very well have low-level
11754            // system locks held, so we want to do this all asynchronously.  And we
11755            // never want this to become fatal, so there is that too.
11756            mHandler.post(new Runnable() {
11757                @Override public void run() {
11758                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11759                }
11760            });
11761            return false;
11762        }
11763
11764        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11765                crashInfo);
11766
11767        if (r != null && r.pid != Process.myPid() &&
11768                Settings.Global.getInt(mContext.getContentResolver(),
11769                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11770            crashApplication(r, crashInfo);
11771            return true;
11772        } else {
11773            return false;
11774        }
11775    }
11776
11777    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11778            final ApplicationErrorReport.CrashInfo crashInfo) {
11779        final ProcessRecord r = findAppProcess(app, "WTF");
11780        final String processName = app == null ? "system_server"
11781                : (r == null ? "unknown" : r.processName);
11782
11783        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11784                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11785
11786        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11787
11788        return r;
11789    }
11790
11791    /**
11792     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11793     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11794     */
11795    private ProcessRecord findAppProcess(IBinder app, String reason) {
11796        if (app == null) {
11797            return null;
11798        }
11799
11800        synchronized (this) {
11801            final int NP = mProcessNames.getMap().size();
11802            for (int ip=0; ip<NP; ip++) {
11803                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11804                final int NA = apps.size();
11805                for (int ia=0; ia<NA; ia++) {
11806                    ProcessRecord p = apps.valueAt(ia);
11807                    if (p.thread != null && p.thread.asBinder() == app) {
11808                        return p;
11809                    }
11810                }
11811            }
11812
11813            Slog.w(TAG, "Can't find mystery application for " + reason
11814                    + " from pid=" + Binder.getCallingPid()
11815                    + " uid=" + Binder.getCallingUid() + ": " + app);
11816            return null;
11817        }
11818    }
11819
11820    /**
11821     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11822     * to append various headers to the dropbox log text.
11823     */
11824    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11825            StringBuilder sb) {
11826        // Watchdog thread ends up invoking this function (with
11827        // a null ProcessRecord) to add the stack file to dropbox.
11828        // Do not acquire a lock on this (am) in such cases, as it
11829        // could cause a potential deadlock, if and when watchdog
11830        // is invoked due to unavailability of lock on am and it
11831        // would prevent watchdog from killing system_server.
11832        if (process == null) {
11833            sb.append("Process: ").append(processName).append("\n");
11834            return;
11835        }
11836        // Note: ProcessRecord 'process' is guarded by the service
11837        // instance.  (notably process.pkgList, which could otherwise change
11838        // concurrently during execution of this method)
11839        synchronized (this) {
11840            sb.append("Process: ").append(processName).append("\n");
11841            int flags = process.info.flags;
11842            IPackageManager pm = AppGlobals.getPackageManager();
11843            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11844            for (int ip=0; ip<process.pkgList.size(); ip++) {
11845                String pkg = process.pkgList.keyAt(ip);
11846                sb.append("Package: ").append(pkg);
11847                try {
11848                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11849                    if (pi != null) {
11850                        sb.append(" v").append(pi.versionCode);
11851                        if (pi.versionName != null) {
11852                            sb.append(" (").append(pi.versionName).append(")");
11853                        }
11854                    }
11855                } catch (RemoteException e) {
11856                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11857                }
11858                sb.append("\n");
11859            }
11860        }
11861    }
11862
11863    private static String processClass(ProcessRecord process) {
11864        if (process == null || process.pid == MY_PID) {
11865            return "system_server";
11866        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11867            return "system_app";
11868        } else {
11869            return "data_app";
11870        }
11871    }
11872
11873    /**
11874     * Write a description of an error (crash, WTF, ANR) to the drop box.
11875     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11876     * @param process which caused the error, null means the system server
11877     * @param activity which triggered the error, null if unknown
11878     * @param parent activity related to the error, null if unknown
11879     * @param subject line related to the error, null if absent
11880     * @param report in long form describing the error, null if absent
11881     * @param logFile to include in the report, null if none
11882     * @param crashInfo giving an application stack trace, null if absent
11883     */
11884    public void addErrorToDropBox(String eventType,
11885            ProcessRecord process, String processName, ActivityRecord activity,
11886            ActivityRecord parent, String subject,
11887            final String report, final File logFile,
11888            final ApplicationErrorReport.CrashInfo crashInfo) {
11889        // NOTE -- this must never acquire the ActivityManagerService lock,
11890        // otherwise the watchdog may be prevented from resetting the system.
11891
11892        final String dropboxTag = processClass(process) + "_" + eventType;
11893        final DropBoxManager dbox = (DropBoxManager)
11894                mContext.getSystemService(Context.DROPBOX_SERVICE);
11895
11896        // Exit early if the dropbox isn't configured to accept this report type.
11897        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11898
11899        final StringBuilder sb = new StringBuilder(1024);
11900        appendDropBoxProcessHeaders(process, processName, sb);
11901        if (activity != null) {
11902            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11903        }
11904        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11905            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11906        }
11907        if (parent != null && parent != activity) {
11908            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11909        }
11910        if (subject != null) {
11911            sb.append("Subject: ").append(subject).append("\n");
11912        }
11913        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11914        if (Debug.isDebuggerConnected()) {
11915            sb.append("Debugger: Connected\n");
11916        }
11917        sb.append("\n");
11918
11919        // Do the rest in a worker thread to avoid blocking the caller on I/O
11920        // (After this point, we shouldn't access AMS internal data structures.)
11921        Thread worker = new Thread("Error dump: " + dropboxTag) {
11922            @Override
11923            public void run() {
11924                if (report != null) {
11925                    sb.append(report);
11926                }
11927                if (logFile != null) {
11928                    try {
11929                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11930                                    "\n\n[[TRUNCATED]]"));
11931                    } catch (IOException e) {
11932                        Slog.e(TAG, "Error reading " + logFile, e);
11933                    }
11934                }
11935                if (crashInfo != null && crashInfo.stackTrace != null) {
11936                    sb.append(crashInfo.stackTrace);
11937                }
11938
11939                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11940                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11941                if (lines > 0) {
11942                    sb.append("\n");
11943
11944                    // Merge several logcat streams, and take the last N lines
11945                    InputStreamReader input = null;
11946                    try {
11947                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11948                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11949                                "-b", "crash",
11950                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11951
11952                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11953                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11954                        input = new InputStreamReader(logcat.getInputStream());
11955
11956                        int num;
11957                        char[] buf = new char[8192];
11958                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11959                    } catch (IOException e) {
11960                        Slog.e(TAG, "Error running logcat", e);
11961                    } finally {
11962                        if (input != null) try { input.close(); } catch (IOException e) {}
11963                    }
11964                }
11965
11966                dbox.addText(dropboxTag, sb.toString());
11967            }
11968        };
11969
11970        if (process == null) {
11971            // If process is null, we are being called from some internal code
11972            // and may be about to die -- run this synchronously.
11973            worker.run();
11974        } else {
11975            worker.start();
11976        }
11977    }
11978
11979    /**
11980     * Bring up the "unexpected error" dialog box for a crashing app.
11981     * Deal with edge cases (intercepts from instrumented applications,
11982     * ActivityController, error intent receivers, that sort of thing).
11983     * @param r the application crashing
11984     * @param crashInfo describing the failure
11985     */
11986    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11987        long timeMillis = System.currentTimeMillis();
11988        String shortMsg = crashInfo.exceptionClassName;
11989        String longMsg = crashInfo.exceptionMessage;
11990        String stackTrace = crashInfo.stackTrace;
11991        if (shortMsg != null && longMsg != null) {
11992            longMsg = shortMsg + ": " + longMsg;
11993        } else if (shortMsg != null) {
11994            longMsg = shortMsg;
11995        }
11996
11997        AppErrorResult result = new AppErrorResult();
11998        synchronized (this) {
11999            if (mController != null) {
12000                try {
12001                    String name = r != null ? r.processName : null;
12002                    int pid = r != null ? r.pid : Binder.getCallingPid();
12003                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12004                    if (!mController.appCrashed(name, pid,
12005                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12006                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12007                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12008                            Slog.w(TAG, "Skip killing native crashed app " + name
12009                                    + "(" + pid + ") during testing");
12010                        } else {
12011                            Slog.w(TAG, "Force-killing crashed app " + name
12012                                    + " at watcher's request");
12013                            if (r != null) {
12014                                r.kill("crash", true);
12015                            } else {
12016                                // Huh.
12017                                Process.killProcess(pid);
12018                                Process.killProcessGroup(uid, pid);
12019                            }
12020                        }
12021                        return;
12022                    }
12023                } catch (RemoteException e) {
12024                    mController = null;
12025                    Watchdog.getInstance().setActivityController(null);
12026                }
12027            }
12028
12029            final long origId = Binder.clearCallingIdentity();
12030
12031            // If this process is running instrumentation, finish it.
12032            if (r != null && r.instrumentationClass != null) {
12033                Slog.w(TAG, "Error in app " + r.processName
12034                      + " running instrumentation " + r.instrumentationClass + ":");
12035                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12036                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12037                Bundle info = new Bundle();
12038                info.putString("shortMsg", shortMsg);
12039                info.putString("longMsg", longMsg);
12040                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12041                Binder.restoreCallingIdentity(origId);
12042                return;
12043            }
12044
12045            // Log crash in battery stats.
12046            if (r != null) {
12047                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12048            }
12049
12050            // If we can't identify the process or it's already exceeded its crash quota,
12051            // quit right away without showing a crash dialog.
12052            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12053                Binder.restoreCallingIdentity(origId);
12054                return;
12055            }
12056
12057            Message msg = Message.obtain();
12058            msg.what = SHOW_ERROR_MSG;
12059            HashMap data = new HashMap();
12060            data.put("result", result);
12061            data.put("app", r);
12062            msg.obj = data;
12063            mHandler.sendMessage(msg);
12064
12065            Binder.restoreCallingIdentity(origId);
12066        }
12067
12068        int res = result.get();
12069
12070        Intent appErrorIntent = null;
12071        synchronized (this) {
12072            if (r != null && !r.isolated) {
12073                // XXX Can't keep track of crash time for isolated processes,
12074                // since they don't have a persistent identity.
12075                mProcessCrashTimes.put(r.info.processName, r.uid,
12076                        SystemClock.uptimeMillis());
12077            }
12078            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12079                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12080            }
12081        }
12082
12083        if (appErrorIntent != null) {
12084            try {
12085                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12086            } catch (ActivityNotFoundException e) {
12087                Slog.w(TAG, "bug report receiver dissappeared", e);
12088            }
12089        }
12090    }
12091
12092    Intent createAppErrorIntentLocked(ProcessRecord r,
12093            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12094        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12095        if (report == null) {
12096            return null;
12097        }
12098        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12099        result.setComponent(r.errorReportReceiver);
12100        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12101        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12102        return result;
12103    }
12104
12105    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12106            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12107        if (r.errorReportReceiver == null) {
12108            return null;
12109        }
12110
12111        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12112            return null;
12113        }
12114
12115        ApplicationErrorReport report = new ApplicationErrorReport();
12116        report.packageName = r.info.packageName;
12117        report.installerPackageName = r.errorReportReceiver.getPackageName();
12118        report.processName = r.processName;
12119        report.time = timeMillis;
12120        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12121
12122        if (r.crashing || r.forceCrashReport) {
12123            report.type = ApplicationErrorReport.TYPE_CRASH;
12124            report.crashInfo = crashInfo;
12125        } else if (r.notResponding) {
12126            report.type = ApplicationErrorReport.TYPE_ANR;
12127            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12128
12129            report.anrInfo.activity = r.notRespondingReport.tag;
12130            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12131            report.anrInfo.info = r.notRespondingReport.longMsg;
12132        }
12133
12134        return report;
12135    }
12136
12137    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12138        enforceNotIsolatedCaller("getProcessesInErrorState");
12139        // assume our apps are happy - lazy create the list
12140        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12141
12142        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12143                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12144        int userId = UserHandle.getUserId(Binder.getCallingUid());
12145
12146        synchronized (this) {
12147
12148            // iterate across all processes
12149            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12150                ProcessRecord app = mLruProcesses.get(i);
12151                if (!allUsers && app.userId != userId) {
12152                    continue;
12153                }
12154                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12155                    // This one's in trouble, so we'll generate a report for it
12156                    // crashes are higher priority (in case there's a crash *and* an anr)
12157                    ActivityManager.ProcessErrorStateInfo report = null;
12158                    if (app.crashing) {
12159                        report = app.crashingReport;
12160                    } else if (app.notResponding) {
12161                        report = app.notRespondingReport;
12162                    }
12163
12164                    if (report != null) {
12165                        if (errList == null) {
12166                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12167                        }
12168                        errList.add(report);
12169                    } else {
12170                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12171                                " crashing = " + app.crashing +
12172                                " notResponding = " + app.notResponding);
12173                    }
12174                }
12175            }
12176        }
12177
12178        return errList;
12179    }
12180
12181    static int procStateToImportance(int procState, int memAdj,
12182            ActivityManager.RunningAppProcessInfo currApp) {
12183        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12184        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12185            currApp.lru = memAdj;
12186        } else {
12187            currApp.lru = 0;
12188        }
12189        return imp;
12190    }
12191
12192    private void fillInProcMemInfo(ProcessRecord app,
12193            ActivityManager.RunningAppProcessInfo outInfo) {
12194        outInfo.pid = app.pid;
12195        outInfo.uid = app.info.uid;
12196        if (mHeavyWeightProcess == app) {
12197            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12198        }
12199        if (app.persistent) {
12200            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12201        }
12202        if (app.activities.size() > 0) {
12203            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12204        }
12205        outInfo.lastTrimLevel = app.trimMemoryLevel;
12206        int adj = app.curAdj;
12207        int procState = app.curProcState;
12208        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12209        outInfo.importanceReasonCode = app.adjTypeCode;
12210        outInfo.processState = app.curProcState;
12211    }
12212
12213    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12214        enforceNotIsolatedCaller("getRunningAppProcesses");
12215        // Lazy instantiation of list
12216        List<ActivityManager.RunningAppProcessInfo> runList = null;
12217        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12218                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12219        int userId = UserHandle.getUserId(Binder.getCallingUid());
12220        synchronized (this) {
12221            // Iterate across all processes
12222            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12223                ProcessRecord app = mLruProcesses.get(i);
12224                if (!allUsers && app.userId != userId) {
12225                    continue;
12226                }
12227                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12228                    // Generate process state info for running application
12229                    ActivityManager.RunningAppProcessInfo currApp =
12230                        new ActivityManager.RunningAppProcessInfo(app.processName,
12231                                app.pid, app.getPackageList());
12232                    fillInProcMemInfo(app, currApp);
12233                    if (app.adjSource instanceof ProcessRecord) {
12234                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12235                        currApp.importanceReasonImportance =
12236                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12237                                        app.adjSourceProcState);
12238                    } else if (app.adjSource instanceof ActivityRecord) {
12239                        ActivityRecord r = (ActivityRecord)app.adjSource;
12240                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12241                    }
12242                    if (app.adjTarget instanceof ComponentName) {
12243                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12244                    }
12245                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12246                    //        + " lru=" + currApp.lru);
12247                    if (runList == null) {
12248                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12249                    }
12250                    runList.add(currApp);
12251                }
12252            }
12253        }
12254        return runList;
12255    }
12256
12257    public List<ApplicationInfo> getRunningExternalApplications() {
12258        enforceNotIsolatedCaller("getRunningExternalApplications");
12259        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12260        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12261        if (runningApps != null && runningApps.size() > 0) {
12262            Set<String> extList = new HashSet<String>();
12263            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12264                if (app.pkgList != null) {
12265                    for (String pkg : app.pkgList) {
12266                        extList.add(pkg);
12267                    }
12268                }
12269            }
12270            IPackageManager pm = AppGlobals.getPackageManager();
12271            for (String pkg : extList) {
12272                try {
12273                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12274                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12275                        retList.add(info);
12276                    }
12277                } catch (RemoteException e) {
12278                }
12279            }
12280        }
12281        return retList;
12282    }
12283
12284    @Override
12285    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12286        enforceNotIsolatedCaller("getMyMemoryState");
12287        synchronized (this) {
12288            ProcessRecord proc;
12289            synchronized (mPidsSelfLocked) {
12290                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12291            }
12292            fillInProcMemInfo(proc, outInfo);
12293        }
12294    }
12295
12296    @Override
12297    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12298        if (checkCallingPermission(android.Manifest.permission.DUMP)
12299                != PackageManager.PERMISSION_GRANTED) {
12300            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12301                    + Binder.getCallingPid()
12302                    + ", uid=" + Binder.getCallingUid()
12303                    + " without permission "
12304                    + android.Manifest.permission.DUMP);
12305            return;
12306        }
12307
12308        boolean dumpAll = false;
12309        boolean dumpClient = false;
12310        String dumpPackage = null;
12311
12312        int opti = 0;
12313        while (opti < args.length) {
12314            String opt = args[opti];
12315            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12316                break;
12317            }
12318            opti++;
12319            if ("-a".equals(opt)) {
12320                dumpAll = true;
12321            } else if ("-c".equals(opt)) {
12322                dumpClient = true;
12323            } else if ("-h".equals(opt)) {
12324                pw.println("Activity manager dump options:");
12325                pw.println("  [-a] [-c] [-h] [cmd] ...");
12326                pw.println("  cmd may be one of:");
12327                pw.println("    a[ctivities]: activity stack state");
12328                pw.println("    r[recents]: recent activities state");
12329                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12330                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12331                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12332                pw.println("    o[om]: out of memory management");
12333                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12334                pw.println("    provider [COMP_SPEC]: provider client-side state");
12335                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12336                pw.println("    service [COMP_SPEC]: service client-side state");
12337                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12338                pw.println("    all: dump all activities");
12339                pw.println("    top: dump the top activity");
12340                pw.println("    write: write all pending state to storage");
12341                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12342                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12343                pw.println("    a partial substring in a component name, a");
12344                pw.println("    hex object identifier.");
12345                pw.println("  -a: include all available server state.");
12346                pw.println("  -c: include client state.");
12347                return;
12348            } else {
12349                pw.println("Unknown argument: " + opt + "; use -h for help");
12350            }
12351        }
12352
12353        long origId = Binder.clearCallingIdentity();
12354        boolean more = false;
12355        // Is the caller requesting to dump a particular piece of data?
12356        if (opti < args.length) {
12357            String cmd = args[opti];
12358            opti++;
12359            if ("activities".equals(cmd) || "a".equals(cmd)) {
12360                synchronized (this) {
12361                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12362                }
12363            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12364                synchronized (this) {
12365                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12366                }
12367            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12368                String[] newArgs;
12369                String name;
12370                if (opti >= args.length) {
12371                    name = null;
12372                    newArgs = EMPTY_STRING_ARRAY;
12373                } else {
12374                    name = args[opti];
12375                    opti++;
12376                    newArgs = new String[args.length - opti];
12377                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12378                            args.length - opti);
12379                }
12380                synchronized (this) {
12381                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12382                }
12383            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12384                String[] newArgs;
12385                String name;
12386                if (opti >= args.length) {
12387                    name = null;
12388                    newArgs = EMPTY_STRING_ARRAY;
12389                } else {
12390                    name = args[opti];
12391                    opti++;
12392                    newArgs = new String[args.length - opti];
12393                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12394                            args.length - opti);
12395                }
12396                synchronized (this) {
12397                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12398                }
12399            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12400                String[] newArgs;
12401                String name;
12402                if (opti >= args.length) {
12403                    name = null;
12404                    newArgs = EMPTY_STRING_ARRAY;
12405                } else {
12406                    name = args[opti];
12407                    opti++;
12408                    newArgs = new String[args.length - opti];
12409                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12410                            args.length - opti);
12411                }
12412                synchronized (this) {
12413                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12414                }
12415            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12416                synchronized (this) {
12417                    dumpOomLocked(fd, pw, args, opti, true);
12418                }
12419            } else if ("provider".equals(cmd)) {
12420                String[] newArgs;
12421                String name;
12422                if (opti >= args.length) {
12423                    name = null;
12424                    newArgs = EMPTY_STRING_ARRAY;
12425                } else {
12426                    name = args[opti];
12427                    opti++;
12428                    newArgs = new String[args.length - opti];
12429                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12430                }
12431                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12432                    pw.println("No providers match: " + name);
12433                    pw.println("Use -h for help.");
12434                }
12435            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12436                synchronized (this) {
12437                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12438                }
12439            } else if ("service".equals(cmd)) {
12440                String[] newArgs;
12441                String name;
12442                if (opti >= args.length) {
12443                    name = null;
12444                    newArgs = EMPTY_STRING_ARRAY;
12445                } else {
12446                    name = args[opti];
12447                    opti++;
12448                    newArgs = new String[args.length - opti];
12449                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12450                            args.length - opti);
12451                }
12452                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12453                    pw.println("No services match: " + name);
12454                    pw.println("Use -h for help.");
12455                }
12456            } else if ("package".equals(cmd)) {
12457                String[] newArgs;
12458                if (opti >= args.length) {
12459                    pw.println("package: no package name specified");
12460                    pw.println("Use -h for help.");
12461                } else {
12462                    dumpPackage = args[opti];
12463                    opti++;
12464                    newArgs = new String[args.length - opti];
12465                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12466                            args.length - opti);
12467                    args = newArgs;
12468                    opti = 0;
12469                    more = true;
12470                }
12471            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12472                synchronized (this) {
12473                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12474                }
12475            } else if ("write".equals(cmd)) {
12476                mTaskPersister.flush();
12477                pw.println("All tasks persisted.");
12478                return;
12479            } else {
12480                // Dumping a single activity?
12481                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12482                    pw.println("Bad activity command, or no activities match: " + cmd);
12483                    pw.println("Use -h for help.");
12484                }
12485            }
12486            if (!more) {
12487                Binder.restoreCallingIdentity(origId);
12488                return;
12489            }
12490        }
12491
12492        // No piece of data specified, dump everything.
12493        synchronized (this) {
12494            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12495            pw.println();
12496            if (dumpAll) {
12497                pw.println("-------------------------------------------------------------------------------");
12498            }
12499            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12500            pw.println();
12501            if (dumpAll) {
12502                pw.println("-------------------------------------------------------------------------------");
12503            }
12504            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12505            pw.println();
12506            if (dumpAll) {
12507                pw.println("-------------------------------------------------------------------------------");
12508            }
12509            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12510            pw.println();
12511            if (dumpAll) {
12512                pw.println("-------------------------------------------------------------------------------");
12513            }
12514            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12515            pw.println();
12516            if (dumpAll) {
12517                pw.println("-------------------------------------------------------------------------------");
12518            }
12519            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12520            pw.println();
12521            if (dumpAll) {
12522                pw.println("-------------------------------------------------------------------------------");
12523            }
12524            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12525        }
12526        Binder.restoreCallingIdentity(origId);
12527    }
12528
12529    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12530            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12531        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12532
12533        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12534                dumpPackage);
12535        boolean needSep = printedAnything;
12536
12537        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12538                dumpPackage, needSep, "  mFocusedActivity: ");
12539        if (printed) {
12540            printedAnything = true;
12541            needSep = false;
12542        }
12543
12544        if (dumpPackage == null) {
12545            if (needSep) {
12546                pw.println();
12547            }
12548            needSep = true;
12549            printedAnything = true;
12550            mStackSupervisor.dump(pw, "  ");
12551        }
12552
12553        if (!printedAnything) {
12554            pw.println("  (nothing)");
12555        }
12556    }
12557
12558    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12559            int opti, boolean dumpAll, String dumpPackage) {
12560        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12561
12562        boolean printedAnything = false;
12563
12564        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12565            boolean printedHeader = false;
12566
12567            final int N = mRecentTasks.size();
12568            for (int i=0; i<N; i++) {
12569                TaskRecord tr = mRecentTasks.get(i);
12570                if (dumpPackage != null) {
12571                    if (tr.realActivity == null ||
12572                            !dumpPackage.equals(tr.realActivity)) {
12573                        continue;
12574                    }
12575                }
12576                if (!printedHeader) {
12577                    pw.println("  Recent tasks:");
12578                    printedHeader = true;
12579                    printedAnything = true;
12580                }
12581                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12582                        pw.println(tr);
12583                if (dumpAll) {
12584                    mRecentTasks.get(i).dump(pw, "    ");
12585                }
12586            }
12587        }
12588
12589        if (!printedAnything) {
12590            pw.println("  (nothing)");
12591        }
12592    }
12593
12594    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12595            int opti, boolean dumpAll, String dumpPackage) {
12596        boolean needSep = false;
12597        boolean printedAnything = false;
12598        int numPers = 0;
12599
12600        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12601
12602        if (dumpAll) {
12603            final int NP = mProcessNames.getMap().size();
12604            for (int ip=0; ip<NP; ip++) {
12605                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12606                final int NA = procs.size();
12607                for (int ia=0; ia<NA; ia++) {
12608                    ProcessRecord r = procs.valueAt(ia);
12609                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12610                        continue;
12611                    }
12612                    if (!needSep) {
12613                        pw.println("  All known processes:");
12614                        needSep = true;
12615                        printedAnything = true;
12616                    }
12617                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12618                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12619                        pw.print(" "); pw.println(r);
12620                    r.dump(pw, "    ");
12621                    if (r.persistent) {
12622                        numPers++;
12623                    }
12624                }
12625            }
12626        }
12627
12628        if (mIsolatedProcesses.size() > 0) {
12629            boolean printed = false;
12630            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12631                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12632                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12633                    continue;
12634                }
12635                if (!printed) {
12636                    if (needSep) {
12637                        pw.println();
12638                    }
12639                    pw.println("  Isolated process list (sorted by uid):");
12640                    printedAnything = true;
12641                    printed = true;
12642                    needSep = true;
12643                }
12644                pw.println(String.format("%sIsolated #%2d: %s",
12645                        "    ", i, r.toString()));
12646            }
12647        }
12648
12649        if (mLruProcesses.size() > 0) {
12650            if (needSep) {
12651                pw.println();
12652            }
12653            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12654                    pw.print(" total, non-act at ");
12655                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12656                    pw.print(", non-svc at ");
12657                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12658                    pw.println("):");
12659            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12660            needSep = true;
12661            printedAnything = true;
12662        }
12663
12664        if (dumpAll || dumpPackage != null) {
12665            synchronized (mPidsSelfLocked) {
12666                boolean printed = false;
12667                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12668                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12669                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12670                        continue;
12671                    }
12672                    if (!printed) {
12673                        if (needSep) pw.println();
12674                        needSep = true;
12675                        pw.println("  PID mappings:");
12676                        printed = true;
12677                        printedAnything = true;
12678                    }
12679                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12680                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12681                }
12682            }
12683        }
12684
12685        if (mForegroundProcesses.size() > 0) {
12686            synchronized (mPidsSelfLocked) {
12687                boolean printed = false;
12688                for (int i=0; i<mForegroundProcesses.size(); i++) {
12689                    ProcessRecord r = mPidsSelfLocked.get(
12690                            mForegroundProcesses.valueAt(i).pid);
12691                    if (dumpPackage != null && (r == null
12692                            || !r.pkgList.containsKey(dumpPackage))) {
12693                        continue;
12694                    }
12695                    if (!printed) {
12696                        if (needSep) pw.println();
12697                        needSep = true;
12698                        pw.println("  Foreground Processes:");
12699                        printed = true;
12700                        printedAnything = true;
12701                    }
12702                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12703                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12704                }
12705            }
12706        }
12707
12708        if (mPersistentStartingProcesses.size() > 0) {
12709            if (needSep) pw.println();
12710            needSep = true;
12711            printedAnything = true;
12712            pw.println("  Persisent processes that are starting:");
12713            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12714                    "Starting Norm", "Restarting PERS", dumpPackage);
12715        }
12716
12717        if (mRemovedProcesses.size() > 0) {
12718            if (needSep) pw.println();
12719            needSep = true;
12720            printedAnything = true;
12721            pw.println("  Processes that are being removed:");
12722            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12723                    "Removed Norm", "Removed PERS", dumpPackage);
12724        }
12725
12726        if (mProcessesOnHold.size() > 0) {
12727            if (needSep) pw.println();
12728            needSep = true;
12729            printedAnything = true;
12730            pw.println("  Processes that are on old until the system is ready:");
12731            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12732                    "OnHold Norm", "OnHold PERS", dumpPackage);
12733        }
12734
12735        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12736
12737        if (mProcessCrashTimes.getMap().size() > 0) {
12738            boolean printed = false;
12739            long now = SystemClock.uptimeMillis();
12740            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12741            final int NP = pmap.size();
12742            for (int ip=0; ip<NP; ip++) {
12743                String pname = pmap.keyAt(ip);
12744                SparseArray<Long> uids = pmap.valueAt(ip);
12745                final int N = uids.size();
12746                for (int i=0; i<N; i++) {
12747                    int puid = uids.keyAt(i);
12748                    ProcessRecord r = mProcessNames.get(pname, puid);
12749                    if (dumpPackage != null && (r == null
12750                            || !r.pkgList.containsKey(dumpPackage))) {
12751                        continue;
12752                    }
12753                    if (!printed) {
12754                        if (needSep) pw.println();
12755                        needSep = true;
12756                        pw.println("  Time since processes crashed:");
12757                        printed = true;
12758                        printedAnything = true;
12759                    }
12760                    pw.print("    Process "); pw.print(pname);
12761                            pw.print(" uid "); pw.print(puid);
12762                            pw.print(": last crashed ");
12763                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12764                            pw.println(" ago");
12765                }
12766            }
12767        }
12768
12769        if (mBadProcesses.getMap().size() > 0) {
12770            boolean printed = false;
12771            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12772            final int NP = pmap.size();
12773            for (int ip=0; ip<NP; ip++) {
12774                String pname = pmap.keyAt(ip);
12775                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12776                final int N = uids.size();
12777                for (int i=0; i<N; i++) {
12778                    int puid = uids.keyAt(i);
12779                    ProcessRecord r = mProcessNames.get(pname, puid);
12780                    if (dumpPackage != null && (r == null
12781                            || !r.pkgList.containsKey(dumpPackage))) {
12782                        continue;
12783                    }
12784                    if (!printed) {
12785                        if (needSep) pw.println();
12786                        needSep = true;
12787                        pw.println("  Bad processes:");
12788                        printedAnything = true;
12789                    }
12790                    BadProcessInfo info = uids.valueAt(i);
12791                    pw.print("    Bad process "); pw.print(pname);
12792                            pw.print(" uid "); pw.print(puid);
12793                            pw.print(": crashed at time "); pw.println(info.time);
12794                    if (info.shortMsg != null) {
12795                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12796                    }
12797                    if (info.longMsg != null) {
12798                        pw.print("      Long msg: "); pw.println(info.longMsg);
12799                    }
12800                    if (info.stack != null) {
12801                        pw.println("      Stack:");
12802                        int lastPos = 0;
12803                        for (int pos=0; pos<info.stack.length(); pos++) {
12804                            if (info.stack.charAt(pos) == '\n') {
12805                                pw.print("        ");
12806                                pw.write(info.stack, lastPos, pos-lastPos);
12807                                pw.println();
12808                                lastPos = pos+1;
12809                            }
12810                        }
12811                        if (lastPos < info.stack.length()) {
12812                            pw.print("        ");
12813                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12814                            pw.println();
12815                        }
12816                    }
12817                }
12818            }
12819        }
12820
12821        if (dumpPackage == null) {
12822            pw.println();
12823            needSep = false;
12824            pw.println("  mStartedUsers:");
12825            for (int i=0; i<mStartedUsers.size(); i++) {
12826                UserStartedState uss = mStartedUsers.valueAt(i);
12827                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12828                        pw.print(": "); uss.dump("", pw);
12829            }
12830            pw.print("  mStartedUserArray: [");
12831            for (int i=0; i<mStartedUserArray.length; i++) {
12832                if (i > 0) pw.print(", ");
12833                pw.print(mStartedUserArray[i]);
12834            }
12835            pw.println("]");
12836            pw.print("  mUserLru: [");
12837            for (int i=0; i<mUserLru.size(); i++) {
12838                if (i > 0) pw.print(", ");
12839                pw.print(mUserLru.get(i));
12840            }
12841            pw.println("]");
12842            if (dumpAll) {
12843                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12844            }
12845            synchronized (mUserProfileGroupIdsSelfLocked) {
12846                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12847                    pw.println("  mUserProfileGroupIds:");
12848                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12849                        pw.print("    User #");
12850                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12851                        pw.print(" -> profile #");
12852                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12853                    }
12854                }
12855            }
12856        }
12857        if (mHomeProcess != null && (dumpPackage == null
12858                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12859            if (needSep) {
12860                pw.println();
12861                needSep = false;
12862            }
12863            pw.println("  mHomeProcess: " + mHomeProcess);
12864        }
12865        if (mPreviousProcess != null && (dumpPackage == null
12866                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12867            if (needSep) {
12868                pw.println();
12869                needSep = false;
12870            }
12871            pw.println("  mPreviousProcess: " + mPreviousProcess);
12872        }
12873        if (dumpAll) {
12874            StringBuilder sb = new StringBuilder(128);
12875            sb.append("  mPreviousProcessVisibleTime: ");
12876            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12877            pw.println(sb);
12878        }
12879        if (mHeavyWeightProcess != null && (dumpPackage == null
12880                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12881            if (needSep) {
12882                pw.println();
12883                needSep = false;
12884            }
12885            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12886        }
12887        if (dumpPackage == null) {
12888            pw.println("  mConfiguration: " + mConfiguration);
12889        }
12890        if (dumpAll) {
12891            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12892            if (mCompatModePackages.getPackages().size() > 0) {
12893                boolean printed = false;
12894                for (Map.Entry<String, Integer> entry
12895                        : mCompatModePackages.getPackages().entrySet()) {
12896                    String pkg = entry.getKey();
12897                    int mode = entry.getValue();
12898                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12899                        continue;
12900                    }
12901                    if (!printed) {
12902                        pw.println("  mScreenCompatPackages:");
12903                        printed = true;
12904                    }
12905                    pw.print("    "); pw.print(pkg); pw.print(": ");
12906                            pw.print(mode); pw.println();
12907                }
12908            }
12909        }
12910        if (dumpPackage == null) {
12911            pw.println("  mWakefulness="
12912                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12913            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12914                    + lockScreenShownToString());
12915            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12916                    + " mTestPssMode=" + mTestPssMode);
12917        }
12918        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12919                || mOrigWaitForDebugger) {
12920            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12921                    || dumpPackage.equals(mOrigDebugApp)) {
12922                if (needSep) {
12923                    pw.println();
12924                    needSep = false;
12925                }
12926                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12927                        + " mDebugTransient=" + mDebugTransient
12928                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12929            }
12930        }
12931        if (mOpenGlTraceApp != null) {
12932            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12933                if (needSep) {
12934                    pw.println();
12935                    needSep = false;
12936                }
12937                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12938            }
12939        }
12940        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12941                || mProfileFd != null) {
12942            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12943                if (needSep) {
12944                    pw.println();
12945                    needSep = false;
12946                }
12947                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12948                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12949                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12950                        + mAutoStopProfiler);
12951                pw.println("  mProfileType=" + mProfileType);
12952            }
12953        }
12954        if (dumpPackage == null) {
12955            if (mAlwaysFinishActivities || mController != null) {
12956                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12957                        + " mController=" + mController);
12958            }
12959            if (dumpAll) {
12960                pw.println("  Total persistent processes: " + numPers);
12961                pw.println("  mProcessesReady=" + mProcessesReady
12962                        + " mSystemReady=" + mSystemReady
12963                        + " mBooted=" + mBooted
12964                        + " mFactoryTest=" + mFactoryTest);
12965                pw.println("  mBooting=" + mBooting
12966                        + " mCallFinishBooting=" + mCallFinishBooting
12967                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12968                pw.print("  mLastPowerCheckRealtime=");
12969                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12970                        pw.println("");
12971                pw.print("  mLastPowerCheckUptime=");
12972                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12973                        pw.println("");
12974                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12975                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12976                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12977                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12978                        + " (" + mLruProcesses.size() + " total)"
12979                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12980                        + " mNumServiceProcs=" + mNumServiceProcs
12981                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12982                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12983                        + " mLastMemoryLevel" + mLastMemoryLevel
12984                        + " mLastNumProcesses" + mLastNumProcesses);
12985                long now = SystemClock.uptimeMillis();
12986                pw.print("  mLastIdleTime=");
12987                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12988                        pw.print(" mLowRamSinceLastIdle=");
12989                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12990                        pw.println();
12991            }
12992        }
12993
12994        if (!printedAnything) {
12995            pw.println("  (nothing)");
12996        }
12997    }
12998
12999    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13000            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13001        if (mProcessesToGc.size() > 0) {
13002            boolean printed = false;
13003            long now = SystemClock.uptimeMillis();
13004            for (int i=0; i<mProcessesToGc.size(); i++) {
13005                ProcessRecord proc = mProcessesToGc.get(i);
13006                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13007                    continue;
13008                }
13009                if (!printed) {
13010                    if (needSep) pw.println();
13011                    needSep = true;
13012                    pw.println("  Processes that are waiting to GC:");
13013                    printed = true;
13014                }
13015                pw.print("    Process "); pw.println(proc);
13016                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13017                        pw.print(", last gced=");
13018                        pw.print(now-proc.lastRequestedGc);
13019                        pw.print(" ms ago, last lowMem=");
13020                        pw.print(now-proc.lastLowMemory);
13021                        pw.println(" ms ago");
13022
13023            }
13024        }
13025        return needSep;
13026    }
13027
13028    void printOomLevel(PrintWriter pw, String name, int adj) {
13029        pw.print("    ");
13030        if (adj >= 0) {
13031            pw.print(' ');
13032            if (adj < 10) pw.print(' ');
13033        } else {
13034            if (adj > -10) pw.print(' ');
13035        }
13036        pw.print(adj);
13037        pw.print(": ");
13038        pw.print(name);
13039        pw.print(" (");
13040        pw.print(mProcessList.getMemLevel(adj)/1024);
13041        pw.println(" kB)");
13042    }
13043
13044    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13045            int opti, boolean dumpAll) {
13046        boolean needSep = false;
13047
13048        if (mLruProcesses.size() > 0) {
13049            if (needSep) pw.println();
13050            needSep = true;
13051            pw.println("  OOM levels:");
13052            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13053            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13054            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13055            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13056            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13057            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13058            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13059            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13060            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13061            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13062            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13063            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13064            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13065            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13066
13067            if (needSep) pw.println();
13068            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13069                    pw.print(" total, non-act at ");
13070                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13071                    pw.print(", non-svc at ");
13072                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13073                    pw.println("):");
13074            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13075            needSep = true;
13076        }
13077
13078        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13079
13080        pw.println();
13081        pw.println("  mHomeProcess: " + mHomeProcess);
13082        pw.println("  mPreviousProcess: " + mPreviousProcess);
13083        if (mHeavyWeightProcess != null) {
13084            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13085        }
13086
13087        return true;
13088    }
13089
13090    /**
13091     * There are three ways to call this:
13092     *  - no provider specified: dump all the providers
13093     *  - a flattened component name that matched an existing provider was specified as the
13094     *    first arg: dump that one provider
13095     *  - the first arg isn't the flattened component name of an existing provider:
13096     *    dump all providers whose component contains the first arg as a substring
13097     */
13098    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13099            int opti, boolean dumpAll) {
13100        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13101    }
13102
13103    static class ItemMatcher {
13104        ArrayList<ComponentName> components;
13105        ArrayList<String> strings;
13106        ArrayList<Integer> objects;
13107        boolean all;
13108
13109        ItemMatcher() {
13110            all = true;
13111        }
13112
13113        void build(String name) {
13114            ComponentName componentName = ComponentName.unflattenFromString(name);
13115            if (componentName != null) {
13116                if (components == null) {
13117                    components = new ArrayList<ComponentName>();
13118                }
13119                components.add(componentName);
13120                all = false;
13121            } else {
13122                int objectId = 0;
13123                // Not a '/' separated full component name; maybe an object ID?
13124                try {
13125                    objectId = Integer.parseInt(name, 16);
13126                    if (objects == null) {
13127                        objects = new ArrayList<Integer>();
13128                    }
13129                    objects.add(objectId);
13130                    all = false;
13131                } catch (RuntimeException e) {
13132                    // Not an integer; just do string match.
13133                    if (strings == null) {
13134                        strings = new ArrayList<String>();
13135                    }
13136                    strings.add(name);
13137                    all = false;
13138                }
13139            }
13140        }
13141
13142        int build(String[] args, int opti) {
13143            for (; opti<args.length; opti++) {
13144                String name = args[opti];
13145                if ("--".equals(name)) {
13146                    return opti+1;
13147                }
13148                build(name);
13149            }
13150            return opti;
13151        }
13152
13153        boolean match(Object object, ComponentName comp) {
13154            if (all) {
13155                return true;
13156            }
13157            if (components != null) {
13158                for (int i=0; i<components.size(); i++) {
13159                    if (components.get(i).equals(comp)) {
13160                        return true;
13161                    }
13162                }
13163            }
13164            if (objects != null) {
13165                for (int i=0; i<objects.size(); i++) {
13166                    if (System.identityHashCode(object) == objects.get(i)) {
13167                        return true;
13168                    }
13169                }
13170            }
13171            if (strings != null) {
13172                String flat = comp.flattenToString();
13173                for (int i=0; i<strings.size(); i++) {
13174                    if (flat.contains(strings.get(i))) {
13175                        return true;
13176                    }
13177                }
13178            }
13179            return false;
13180        }
13181    }
13182
13183    /**
13184     * There are three things that cmd can be:
13185     *  - a flattened component name that matches an existing activity
13186     *  - the cmd arg isn't the flattened component name of an existing activity:
13187     *    dump all activity whose component contains the cmd as a substring
13188     *  - A hex number of the ActivityRecord object instance.
13189     */
13190    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13191            int opti, boolean dumpAll) {
13192        ArrayList<ActivityRecord> activities;
13193
13194        synchronized (this) {
13195            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13196        }
13197
13198        if (activities.size() <= 0) {
13199            return false;
13200        }
13201
13202        String[] newArgs = new String[args.length - opti];
13203        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13204
13205        TaskRecord lastTask = null;
13206        boolean needSep = false;
13207        for (int i=activities.size()-1; i>=0; i--) {
13208            ActivityRecord r = activities.get(i);
13209            if (needSep) {
13210                pw.println();
13211            }
13212            needSep = true;
13213            synchronized (this) {
13214                if (lastTask != r.task) {
13215                    lastTask = r.task;
13216                    pw.print("TASK "); pw.print(lastTask.affinity);
13217                            pw.print(" id="); pw.println(lastTask.taskId);
13218                    if (dumpAll) {
13219                        lastTask.dump(pw, "  ");
13220                    }
13221                }
13222            }
13223            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13224        }
13225        return true;
13226    }
13227
13228    /**
13229     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13230     * there is a thread associated with the activity.
13231     */
13232    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13233            final ActivityRecord r, String[] args, boolean dumpAll) {
13234        String innerPrefix = prefix + "  ";
13235        synchronized (this) {
13236            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13237                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13238                    pw.print(" pid=");
13239                    if (r.app != null) pw.println(r.app.pid);
13240                    else pw.println("(not running)");
13241            if (dumpAll) {
13242                r.dump(pw, innerPrefix);
13243            }
13244        }
13245        if (r.app != null && r.app.thread != null) {
13246            // flush anything that is already in the PrintWriter since the thread is going
13247            // to write to the file descriptor directly
13248            pw.flush();
13249            try {
13250                TransferPipe tp = new TransferPipe();
13251                try {
13252                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13253                            r.appToken, innerPrefix, args);
13254                    tp.go(fd);
13255                } finally {
13256                    tp.kill();
13257                }
13258            } catch (IOException e) {
13259                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13260            } catch (RemoteException e) {
13261                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13262            }
13263        }
13264    }
13265
13266    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13267            int opti, boolean dumpAll, String dumpPackage) {
13268        boolean needSep = false;
13269        boolean onlyHistory = false;
13270        boolean printedAnything = false;
13271
13272        if ("history".equals(dumpPackage)) {
13273            if (opti < args.length && "-s".equals(args[opti])) {
13274                dumpAll = false;
13275            }
13276            onlyHistory = true;
13277            dumpPackage = null;
13278        }
13279
13280        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13281        if (!onlyHistory && dumpAll) {
13282            if (mRegisteredReceivers.size() > 0) {
13283                boolean printed = false;
13284                Iterator it = mRegisteredReceivers.values().iterator();
13285                while (it.hasNext()) {
13286                    ReceiverList r = (ReceiverList)it.next();
13287                    if (dumpPackage != null && (r.app == null ||
13288                            !dumpPackage.equals(r.app.info.packageName))) {
13289                        continue;
13290                    }
13291                    if (!printed) {
13292                        pw.println("  Registered Receivers:");
13293                        needSep = true;
13294                        printed = true;
13295                        printedAnything = true;
13296                    }
13297                    pw.print("  * "); pw.println(r);
13298                    r.dump(pw, "    ");
13299                }
13300            }
13301
13302            if (mReceiverResolver.dump(pw, needSep ?
13303                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13304                    "    ", dumpPackage, false, false)) {
13305                needSep = true;
13306                printedAnything = true;
13307            }
13308        }
13309
13310        for (BroadcastQueue q : mBroadcastQueues) {
13311            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13312            printedAnything |= needSep;
13313        }
13314
13315        needSep = true;
13316
13317        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13318            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13319                if (needSep) {
13320                    pw.println();
13321                }
13322                needSep = true;
13323                printedAnything = true;
13324                pw.print("  Sticky broadcasts for user ");
13325                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13326                StringBuilder sb = new StringBuilder(128);
13327                for (Map.Entry<String, ArrayList<Intent>> ent
13328                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13329                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13330                    if (dumpAll) {
13331                        pw.println(":");
13332                        ArrayList<Intent> intents = ent.getValue();
13333                        final int N = intents.size();
13334                        for (int i=0; i<N; i++) {
13335                            sb.setLength(0);
13336                            sb.append("    Intent: ");
13337                            intents.get(i).toShortString(sb, false, true, false, false);
13338                            pw.println(sb.toString());
13339                            Bundle bundle = intents.get(i).getExtras();
13340                            if (bundle != null) {
13341                                pw.print("      ");
13342                                pw.println(bundle.toString());
13343                            }
13344                        }
13345                    } else {
13346                        pw.println("");
13347                    }
13348                }
13349            }
13350        }
13351
13352        if (!onlyHistory && dumpAll) {
13353            pw.println();
13354            for (BroadcastQueue queue : mBroadcastQueues) {
13355                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13356                        + queue.mBroadcastsScheduled);
13357            }
13358            pw.println("  mHandler:");
13359            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13360            needSep = true;
13361            printedAnything = true;
13362        }
13363
13364        if (!printedAnything) {
13365            pw.println("  (nothing)");
13366        }
13367    }
13368
13369    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13370            int opti, boolean dumpAll, String dumpPackage) {
13371        boolean needSep;
13372        boolean printedAnything = false;
13373
13374        ItemMatcher matcher = new ItemMatcher();
13375        matcher.build(args, opti);
13376
13377        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13378
13379        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13380        printedAnything |= needSep;
13381
13382        if (mLaunchingProviders.size() > 0) {
13383            boolean printed = false;
13384            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13385                ContentProviderRecord r = mLaunchingProviders.get(i);
13386                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13387                    continue;
13388                }
13389                if (!printed) {
13390                    if (needSep) pw.println();
13391                    needSep = true;
13392                    pw.println("  Launching content providers:");
13393                    printed = true;
13394                    printedAnything = true;
13395                }
13396                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13397                        pw.println(r);
13398            }
13399        }
13400
13401        if (mGrantedUriPermissions.size() > 0) {
13402            boolean printed = false;
13403            int dumpUid = -2;
13404            if (dumpPackage != null) {
13405                try {
13406                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13407                } catch (NameNotFoundException e) {
13408                    dumpUid = -1;
13409                }
13410            }
13411            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13412                int uid = mGrantedUriPermissions.keyAt(i);
13413                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13414                    continue;
13415                }
13416                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13417                if (!printed) {
13418                    if (needSep) pw.println();
13419                    needSep = true;
13420                    pw.println("  Granted Uri Permissions:");
13421                    printed = true;
13422                    printedAnything = true;
13423                }
13424                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13425                for (UriPermission perm : perms.values()) {
13426                    pw.print("    "); pw.println(perm);
13427                    if (dumpAll) {
13428                        perm.dump(pw, "      ");
13429                    }
13430                }
13431            }
13432        }
13433
13434        if (!printedAnything) {
13435            pw.println("  (nothing)");
13436        }
13437    }
13438
13439    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13440            int opti, boolean dumpAll, String dumpPackage) {
13441        boolean printed = false;
13442
13443        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13444
13445        if (mIntentSenderRecords.size() > 0) {
13446            Iterator<WeakReference<PendingIntentRecord>> it
13447                    = mIntentSenderRecords.values().iterator();
13448            while (it.hasNext()) {
13449                WeakReference<PendingIntentRecord> ref = it.next();
13450                PendingIntentRecord rec = ref != null ? ref.get(): null;
13451                if (dumpPackage != null && (rec == null
13452                        || !dumpPackage.equals(rec.key.packageName))) {
13453                    continue;
13454                }
13455                printed = true;
13456                if (rec != null) {
13457                    pw.print("  * "); pw.println(rec);
13458                    if (dumpAll) {
13459                        rec.dump(pw, "    ");
13460                    }
13461                } else {
13462                    pw.print("  * "); pw.println(ref);
13463                }
13464            }
13465        }
13466
13467        if (!printed) {
13468            pw.println("  (nothing)");
13469        }
13470    }
13471
13472    private static final int dumpProcessList(PrintWriter pw,
13473            ActivityManagerService service, List list,
13474            String prefix, String normalLabel, String persistentLabel,
13475            String dumpPackage) {
13476        int numPers = 0;
13477        final int N = list.size()-1;
13478        for (int i=N; i>=0; i--) {
13479            ProcessRecord r = (ProcessRecord)list.get(i);
13480            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13481                continue;
13482            }
13483            pw.println(String.format("%s%s #%2d: %s",
13484                    prefix, (r.persistent ? persistentLabel : normalLabel),
13485                    i, r.toString()));
13486            if (r.persistent) {
13487                numPers++;
13488            }
13489        }
13490        return numPers;
13491    }
13492
13493    private static final boolean dumpProcessOomList(PrintWriter pw,
13494            ActivityManagerService service, List<ProcessRecord> origList,
13495            String prefix, String normalLabel, String persistentLabel,
13496            boolean inclDetails, String dumpPackage) {
13497
13498        ArrayList<Pair<ProcessRecord, Integer>> list
13499                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13500        for (int i=0; i<origList.size(); i++) {
13501            ProcessRecord r = origList.get(i);
13502            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13503                continue;
13504            }
13505            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13506        }
13507
13508        if (list.size() <= 0) {
13509            return false;
13510        }
13511
13512        Comparator<Pair<ProcessRecord, Integer>> comparator
13513                = new Comparator<Pair<ProcessRecord, Integer>>() {
13514            @Override
13515            public int compare(Pair<ProcessRecord, Integer> object1,
13516                    Pair<ProcessRecord, Integer> object2) {
13517                if (object1.first.setAdj != object2.first.setAdj) {
13518                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13519                }
13520                if (object1.second.intValue() != object2.second.intValue()) {
13521                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13522                }
13523                return 0;
13524            }
13525        };
13526
13527        Collections.sort(list, comparator);
13528
13529        final long curRealtime = SystemClock.elapsedRealtime();
13530        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13531        final long curUptime = SystemClock.uptimeMillis();
13532        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13533
13534        for (int i=list.size()-1; i>=0; i--) {
13535            ProcessRecord r = list.get(i).first;
13536            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13537            char schedGroup;
13538            switch (r.setSchedGroup) {
13539                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13540                    schedGroup = 'B';
13541                    break;
13542                case Process.THREAD_GROUP_DEFAULT:
13543                    schedGroup = 'F';
13544                    break;
13545                default:
13546                    schedGroup = '?';
13547                    break;
13548            }
13549            char foreground;
13550            if (r.foregroundActivities) {
13551                foreground = 'A';
13552            } else if (r.foregroundServices) {
13553                foreground = 'S';
13554            } else {
13555                foreground = ' ';
13556            }
13557            String procState = ProcessList.makeProcStateString(r.curProcState);
13558            pw.print(prefix);
13559            pw.print(r.persistent ? persistentLabel : normalLabel);
13560            pw.print(" #");
13561            int num = (origList.size()-1)-list.get(i).second;
13562            if (num < 10) pw.print(' ');
13563            pw.print(num);
13564            pw.print(": ");
13565            pw.print(oomAdj);
13566            pw.print(' ');
13567            pw.print(schedGroup);
13568            pw.print('/');
13569            pw.print(foreground);
13570            pw.print('/');
13571            pw.print(procState);
13572            pw.print(" trm:");
13573            if (r.trimMemoryLevel < 10) pw.print(' ');
13574            pw.print(r.trimMemoryLevel);
13575            pw.print(' ');
13576            pw.print(r.toShortString());
13577            pw.print(" (");
13578            pw.print(r.adjType);
13579            pw.println(')');
13580            if (r.adjSource != null || r.adjTarget != null) {
13581                pw.print(prefix);
13582                pw.print("    ");
13583                if (r.adjTarget instanceof ComponentName) {
13584                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13585                } else if (r.adjTarget != null) {
13586                    pw.print(r.adjTarget.toString());
13587                } else {
13588                    pw.print("{null}");
13589                }
13590                pw.print("<=");
13591                if (r.adjSource instanceof ProcessRecord) {
13592                    pw.print("Proc{");
13593                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13594                    pw.println("}");
13595                } else if (r.adjSource != null) {
13596                    pw.println(r.adjSource.toString());
13597                } else {
13598                    pw.println("{null}");
13599                }
13600            }
13601            if (inclDetails) {
13602                pw.print(prefix);
13603                pw.print("    ");
13604                pw.print("oom: max="); pw.print(r.maxAdj);
13605                pw.print(" curRaw="); pw.print(r.curRawAdj);
13606                pw.print(" setRaw="); pw.print(r.setRawAdj);
13607                pw.print(" cur="); pw.print(r.curAdj);
13608                pw.print(" set="); pw.println(r.setAdj);
13609                pw.print(prefix);
13610                pw.print("    ");
13611                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13612                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13613                pw.print(" lastPss="); pw.print(r.lastPss);
13614                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13615                pw.print(prefix);
13616                pw.print("    ");
13617                pw.print("cached="); pw.print(r.cached);
13618                pw.print(" empty="); pw.print(r.empty);
13619                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13620
13621                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13622                    if (r.lastWakeTime != 0) {
13623                        long wtime;
13624                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13625                        synchronized (stats) {
13626                            wtime = stats.getProcessWakeTime(r.info.uid,
13627                                    r.pid, curRealtime);
13628                        }
13629                        long timeUsed = wtime - r.lastWakeTime;
13630                        pw.print(prefix);
13631                        pw.print("    ");
13632                        pw.print("keep awake over ");
13633                        TimeUtils.formatDuration(realtimeSince, pw);
13634                        pw.print(" used ");
13635                        TimeUtils.formatDuration(timeUsed, pw);
13636                        pw.print(" (");
13637                        pw.print((timeUsed*100)/realtimeSince);
13638                        pw.println("%)");
13639                    }
13640                    if (r.lastCpuTime != 0) {
13641                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13642                        pw.print(prefix);
13643                        pw.print("    ");
13644                        pw.print("run cpu over ");
13645                        TimeUtils.formatDuration(uptimeSince, pw);
13646                        pw.print(" used ");
13647                        TimeUtils.formatDuration(timeUsed, pw);
13648                        pw.print(" (");
13649                        pw.print((timeUsed*100)/uptimeSince);
13650                        pw.println("%)");
13651                    }
13652                }
13653            }
13654        }
13655        return true;
13656    }
13657
13658    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13659            String[] args) {
13660        ArrayList<ProcessRecord> procs;
13661        synchronized (this) {
13662            if (args != null && args.length > start
13663                    && args[start].charAt(0) != '-') {
13664                procs = new ArrayList<ProcessRecord>();
13665                int pid = -1;
13666                try {
13667                    pid = Integer.parseInt(args[start]);
13668                } catch (NumberFormatException e) {
13669                }
13670                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13671                    ProcessRecord proc = mLruProcesses.get(i);
13672                    if (proc.pid == pid) {
13673                        procs.add(proc);
13674                    } else if (allPkgs && proc.pkgList != null
13675                            && proc.pkgList.containsKey(args[start])) {
13676                        procs.add(proc);
13677                    } else if (proc.processName.equals(args[start])) {
13678                        procs.add(proc);
13679                    }
13680                }
13681                if (procs.size() <= 0) {
13682                    return null;
13683                }
13684            } else {
13685                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13686            }
13687        }
13688        return procs;
13689    }
13690
13691    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13692            PrintWriter pw, String[] args) {
13693        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13694        if (procs == null) {
13695            pw.println("No process found for: " + args[0]);
13696            return;
13697        }
13698
13699        long uptime = SystemClock.uptimeMillis();
13700        long realtime = SystemClock.elapsedRealtime();
13701        pw.println("Applications Graphics Acceleration Info:");
13702        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13703
13704        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13705            ProcessRecord r = procs.get(i);
13706            if (r.thread != null) {
13707                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13708                pw.flush();
13709                try {
13710                    TransferPipe tp = new TransferPipe();
13711                    try {
13712                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13713                        tp.go(fd);
13714                    } finally {
13715                        tp.kill();
13716                    }
13717                } catch (IOException e) {
13718                    pw.println("Failure while dumping the app: " + r);
13719                    pw.flush();
13720                } catch (RemoteException e) {
13721                    pw.println("Got a RemoteException while dumping the app " + r);
13722                    pw.flush();
13723                }
13724            }
13725        }
13726    }
13727
13728    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13729        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13730        if (procs == null) {
13731            pw.println("No process found for: " + args[0]);
13732            return;
13733        }
13734
13735        pw.println("Applications Database Info:");
13736
13737        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13738            ProcessRecord r = procs.get(i);
13739            if (r.thread != null) {
13740                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13741                pw.flush();
13742                try {
13743                    TransferPipe tp = new TransferPipe();
13744                    try {
13745                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13746                        tp.go(fd);
13747                    } finally {
13748                        tp.kill();
13749                    }
13750                } catch (IOException e) {
13751                    pw.println("Failure while dumping the app: " + r);
13752                    pw.flush();
13753                } catch (RemoteException e) {
13754                    pw.println("Got a RemoteException while dumping the app " + r);
13755                    pw.flush();
13756                }
13757            }
13758        }
13759    }
13760
13761    final static class MemItem {
13762        final boolean isProc;
13763        final String label;
13764        final String shortLabel;
13765        final long pss;
13766        final int id;
13767        final boolean hasActivities;
13768        ArrayList<MemItem> subitems;
13769
13770        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13771                boolean _hasActivities) {
13772            isProc = true;
13773            label = _label;
13774            shortLabel = _shortLabel;
13775            pss = _pss;
13776            id = _id;
13777            hasActivities = _hasActivities;
13778        }
13779
13780        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13781            isProc = false;
13782            label = _label;
13783            shortLabel = _shortLabel;
13784            pss = _pss;
13785            id = _id;
13786            hasActivities = false;
13787        }
13788    }
13789
13790    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13791            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13792        if (sort && !isCompact) {
13793            Collections.sort(items, new Comparator<MemItem>() {
13794                @Override
13795                public int compare(MemItem lhs, MemItem rhs) {
13796                    if (lhs.pss < rhs.pss) {
13797                        return 1;
13798                    } else if (lhs.pss > rhs.pss) {
13799                        return -1;
13800                    }
13801                    return 0;
13802                }
13803            });
13804        }
13805
13806        for (int i=0; i<items.size(); i++) {
13807            MemItem mi = items.get(i);
13808            if (!isCompact) {
13809                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13810            } else if (mi.isProc) {
13811                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13812                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13813                pw.println(mi.hasActivities ? ",a" : ",e");
13814            } else {
13815                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13816                pw.println(mi.pss);
13817            }
13818            if (mi.subitems != null) {
13819                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13820                        true, isCompact);
13821            }
13822        }
13823    }
13824
13825    // These are in KB.
13826    static final long[] DUMP_MEM_BUCKETS = new long[] {
13827        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13828        120*1024, 160*1024, 200*1024,
13829        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13830        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13831    };
13832
13833    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13834            boolean stackLike) {
13835        int start = label.lastIndexOf('.');
13836        if (start >= 0) start++;
13837        else start = 0;
13838        int end = label.length();
13839        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13840            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13841                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13842                out.append(bucket);
13843                out.append(stackLike ? "MB." : "MB ");
13844                out.append(label, start, end);
13845                return;
13846            }
13847        }
13848        out.append(memKB/1024);
13849        out.append(stackLike ? "MB." : "MB ");
13850        out.append(label, start, end);
13851    }
13852
13853    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13854            ProcessList.NATIVE_ADJ,
13855            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13856            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13857            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13858            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13859            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13860            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13861    };
13862    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13863            "Native",
13864            "System", "Persistent", "Persistent Service", "Foreground",
13865            "Visible", "Perceptible",
13866            "Heavy Weight", "Backup",
13867            "A Services", "Home",
13868            "Previous", "B Services", "Cached"
13869    };
13870    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13871            "native",
13872            "sys", "pers", "persvc", "fore",
13873            "vis", "percept",
13874            "heavy", "backup",
13875            "servicea", "home",
13876            "prev", "serviceb", "cached"
13877    };
13878
13879    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13880            long realtime, boolean isCheckinRequest, boolean isCompact) {
13881        if (isCheckinRequest || isCompact) {
13882            // short checkin version
13883            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13884        } else {
13885            pw.println("Applications Memory Usage (kB):");
13886            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13887        }
13888    }
13889
13890    private static final int KSM_SHARED = 0;
13891    private static final int KSM_SHARING = 1;
13892    private static final int KSM_UNSHARED = 2;
13893    private static final int KSM_VOLATILE = 3;
13894
13895    private final long[] getKsmInfo() {
13896        long[] longOut = new long[4];
13897        final int[] SINGLE_LONG_FORMAT = new int[] {
13898            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13899        };
13900        long[] longTmp = new long[1];
13901        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13902                SINGLE_LONG_FORMAT, null, longTmp, null);
13903        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13904        longTmp[0] = 0;
13905        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13906                SINGLE_LONG_FORMAT, null, longTmp, null);
13907        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13908        longTmp[0] = 0;
13909        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13910                SINGLE_LONG_FORMAT, null, longTmp, null);
13911        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13912        longTmp[0] = 0;
13913        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13914                SINGLE_LONG_FORMAT, null, longTmp, null);
13915        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13916        return longOut;
13917    }
13918
13919    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13920            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13921        boolean dumpDetails = false;
13922        boolean dumpFullDetails = false;
13923        boolean dumpDalvik = false;
13924        boolean oomOnly = false;
13925        boolean isCompact = false;
13926        boolean localOnly = false;
13927        boolean packages = false;
13928
13929        int opti = 0;
13930        while (opti < args.length) {
13931            String opt = args[opti];
13932            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13933                break;
13934            }
13935            opti++;
13936            if ("-a".equals(opt)) {
13937                dumpDetails = true;
13938                dumpFullDetails = true;
13939                dumpDalvik = true;
13940            } else if ("-d".equals(opt)) {
13941                dumpDalvik = true;
13942            } else if ("-c".equals(opt)) {
13943                isCompact = true;
13944            } else if ("--oom".equals(opt)) {
13945                oomOnly = true;
13946            } else if ("--local".equals(opt)) {
13947                localOnly = true;
13948            } else if ("--package".equals(opt)) {
13949                packages = true;
13950            } else if ("-h".equals(opt)) {
13951                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13952                pw.println("  -a: include all available information for each process.");
13953                pw.println("  -d: include dalvik details when dumping process details.");
13954                pw.println("  -c: dump in a compact machine-parseable representation.");
13955                pw.println("  --oom: only show processes organized by oom adj.");
13956                pw.println("  --local: only collect details locally, don't call process.");
13957                pw.println("  --package: interpret process arg as package, dumping all");
13958                pw.println("             processes that have loaded that package.");
13959                pw.println("If [process] is specified it can be the name or ");
13960                pw.println("pid of a specific process to dump.");
13961                return;
13962            } else {
13963                pw.println("Unknown argument: " + opt + "; use -h for help");
13964            }
13965        }
13966
13967        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13968        long uptime = SystemClock.uptimeMillis();
13969        long realtime = SystemClock.elapsedRealtime();
13970        final long[] tmpLong = new long[1];
13971
13972        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13973        if (procs == null) {
13974            // No Java processes.  Maybe they want to print a native process.
13975            if (args != null && args.length > opti
13976                    && args[opti].charAt(0) != '-') {
13977                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13978                        = new ArrayList<ProcessCpuTracker.Stats>();
13979                updateCpuStatsNow();
13980                int findPid = -1;
13981                try {
13982                    findPid = Integer.parseInt(args[opti]);
13983                } catch (NumberFormatException e) {
13984                }
13985                synchronized (mProcessCpuTracker) {
13986                    final int N = mProcessCpuTracker.countStats();
13987                    for (int i=0; i<N; i++) {
13988                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13989                        if (st.pid == findPid || (st.baseName != null
13990                                && st.baseName.equals(args[opti]))) {
13991                            nativeProcs.add(st);
13992                        }
13993                    }
13994                }
13995                if (nativeProcs.size() > 0) {
13996                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13997                            isCompact);
13998                    Debug.MemoryInfo mi = null;
13999                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14000                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14001                        final int pid = r.pid;
14002                        if (!isCheckinRequest && dumpDetails) {
14003                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14004                        }
14005                        if (mi == null) {
14006                            mi = new Debug.MemoryInfo();
14007                        }
14008                        if (dumpDetails || (!brief && !oomOnly)) {
14009                            Debug.getMemoryInfo(pid, mi);
14010                        } else {
14011                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14012                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14013                        }
14014                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14015                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14016                        if (isCheckinRequest) {
14017                            pw.println();
14018                        }
14019                    }
14020                    return;
14021                }
14022            }
14023            pw.println("No process found for: " + args[opti]);
14024            return;
14025        }
14026
14027        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14028            dumpDetails = true;
14029        }
14030
14031        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14032
14033        String[] innerArgs = new String[args.length-opti];
14034        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14035
14036        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14037        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14038        long nativePss = 0;
14039        long dalvikPss = 0;
14040        long otherPss = 0;
14041        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14042
14043        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14044        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14045                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14046
14047        long totalPss = 0;
14048        long cachedPss = 0;
14049
14050        Debug.MemoryInfo mi = null;
14051        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14052            final ProcessRecord r = procs.get(i);
14053            final IApplicationThread thread;
14054            final int pid;
14055            final int oomAdj;
14056            final boolean hasActivities;
14057            synchronized (this) {
14058                thread = r.thread;
14059                pid = r.pid;
14060                oomAdj = r.getSetAdjWithServices();
14061                hasActivities = r.activities.size() > 0;
14062            }
14063            if (thread != null) {
14064                if (!isCheckinRequest && dumpDetails) {
14065                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14066                }
14067                if (mi == null) {
14068                    mi = new Debug.MemoryInfo();
14069                }
14070                if (dumpDetails || (!brief && !oomOnly)) {
14071                    Debug.getMemoryInfo(pid, mi);
14072                } else {
14073                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14074                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14075                }
14076                if (dumpDetails) {
14077                    if (localOnly) {
14078                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14079                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14080                        if (isCheckinRequest) {
14081                            pw.println();
14082                        }
14083                    } else {
14084                        try {
14085                            pw.flush();
14086                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14087                                    dumpDalvik, innerArgs);
14088                        } catch (RemoteException e) {
14089                            if (!isCheckinRequest) {
14090                                pw.println("Got RemoteException!");
14091                                pw.flush();
14092                            }
14093                        }
14094                    }
14095                }
14096
14097                final long myTotalPss = mi.getTotalPss();
14098                final long myTotalUss = mi.getTotalUss();
14099
14100                synchronized (this) {
14101                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14102                        // Record this for posterity if the process has been stable.
14103                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14104                    }
14105                }
14106
14107                if (!isCheckinRequest && mi != null) {
14108                    totalPss += myTotalPss;
14109                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14110                            (hasActivities ? " / activities)" : ")"),
14111                            r.processName, myTotalPss, pid, hasActivities);
14112                    procMems.add(pssItem);
14113                    procMemsMap.put(pid, pssItem);
14114
14115                    nativePss += mi.nativePss;
14116                    dalvikPss += mi.dalvikPss;
14117                    otherPss += mi.otherPss;
14118                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14119                        long mem = mi.getOtherPss(j);
14120                        miscPss[j] += mem;
14121                        otherPss -= mem;
14122                    }
14123
14124                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14125                        cachedPss += myTotalPss;
14126                    }
14127
14128                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14129                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14130                                || oomIndex == (oomPss.length-1)) {
14131                            oomPss[oomIndex] += myTotalPss;
14132                            if (oomProcs[oomIndex] == null) {
14133                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14134                            }
14135                            oomProcs[oomIndex].add(pssItem);
14136                            break;
14137                        }
14138                    }
14139                }
14140            }
14141        }
14142
14143        long nativeProcTotalPss = 0;
14144
14145        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14146            // If we are showing aggregations, also look for native processes to
14147            // include so that our aggregations are more accurate.
14148            updateCpuStatsNow();
14149            mi = null;
14150            synchronized (mProcessCpuTracker) {
14151                final int N = mProcessCpuTracker.countStats();
14152                for (int i=0; i<N; i++) {
14153                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14154                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14155                        if (mi == null) {
14156                            mi = new Debug.MemoryInfo();
14157                        }
14158                        if (!brief && !oomOnly) {
14159                            Debug.getMemoryInfo(st.pid, mi);
14160                        } else {
14161                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14162                            mi.nativePrivateDirty = (int)tmpLong[0];
14163                        }
14164
14165                        final long myTotalPss = mi.getTotalPss();
14166                        totalPss += myTotalPss;
14167                        nativeProcTotalPss += myTotalPss;
14168
14169                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14170                                st.name, myTotalPss, st.pid, false);
14171                        procMems.add(pssItem);
14172
14173                        nativePss += mi.nativePss;
14174                        dalvikPss += mi.dalvikPss;
14175                        otherPss += mi.otherPss;
14176                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14177                            long mem = mi.getOtherPss(j);
14178                            miscPss[j] += mem;
14179                            otherPss -= mem;
14180                        }
14181                        oomPss[0] += myTotalPss;
14182                        if (oomProcs[0] == null) {
14183                            oomProcs[0] = new ArrayList<MemItem>();
14184                        }
14185                        oomProcs[0].add(pssItem);
14186                    }
14187                }
14188            }
14189
14190            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14191
14192            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14193            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14194            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14195            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14196                String label = Debug.MemoryInfo.getOtherLabel(j);
14197                catMems.add(new MemItem(label, label, miscPss[j], j));
14198            }
14199
14200            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14201            for (int j=0; j<oomPss.length; j++) {
14202                if (oomPss[j] != 0) {
14203                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14204                            : DUMP_MEM_OOM_LABEL[j];
14205                    MemItem item = new MemItem(label, label, oomPss[j],
14206                            DUMP_MEM_OOM_ADJ[j]);
14207                    item.subitems = oomProcs[j];
14208                    oomMems.add(item);
14209                }
14210            }
14211
14212            if (!brief && !oomOnly && !isCompact) {
14213                pw.println();
14214                pw.println("Total PSS by process:");
14215                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14216                pw.println();
14217            }
14218            if (!isCompact) {
14219                pw.println("Total PSS by OOM adjustment:");
14220            }
14221            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14222            if (!brief && !oomOnly) {
14223                PrintWriter out = categoryPw != null ? categoryPw : pw;
14224                if (!isCompact) {
14225                    out.println();
14226                    out.println("Total PSS by category:");
14227                }
14228                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14229            }
14230            if (!isCompact) {
14231                pw.println();
14232            }
14233            MemInfoReader memInfo = new MemInfoReader();
14234            memInfo.readMemInfo();
14235            if (nativeProcTotalPss > 0) {
14236                synchronized (this) {
14237                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14238                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14239                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14240                }
14241            }
14242            if (!brief) {
14243                if (!isCompact) {
14244                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14245                    pw.print(" kB (status ");
14246                    switch (mLastMemoryLevel) {
14247                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14248                            pw.println("normal)");
14249                            break;
14250                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14251                            pw.println("moderate)");
14252                            break;
14253                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14254                            pw.println("low)");
14255                            break;
14256                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14257                            pw.println("critical)");
14258                            break;
14259                        default:
14260                            pw.print(mLastMemoryLevel);
14261                            pw.println(")");
14262                            break;
14263                    }
14264                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14265                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14266                            pw.print(cachedPss); pw.print(" cached pss + ");
14267                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14268                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14269                } else {
14270                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14271                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14272                            + memInfo.getFreeSizeKb()); pw.print(",");
14273                    pw.println(totalPss - cachedPss);
14274                }
14275            }
14276            if (!isCompact) {
14277                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14278                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14279                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14280                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14281                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14282                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14283                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14284            }
14285            if (!brief) {
14286                if (memInfo.getZramTotalSizeKb() != 0) {
14287                    if (!isCompact) {
14288                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14289                                pw.print(" kB physical used for ");
14290                                pw.print(memInfo.getSwapTotalSizeKb()
14291                                        - memInfo.getSwapFreeSizeKb());
14292                                pw.print(" kB in swap (");
14293                                pw.print(memInfo.getSwapTotalSizeKb());
14294                                pw.println(" kB total swap)");
14295                    } else {
14296                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14297                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14298                                pw.println(memInfo.getSwapFreeSizeKb());
14299                    }
14300                }
14301                final long[] ksm = getKsmInfo();
14302                if (!isCompact) {
14303                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14304                            || ksm[KSM_VOLATILE] != 0) {
14305                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14306                                pw.print(" kB saved from shared ");
14307                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14308                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14309                                pw.print(" kB unshared; ");
14310                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14311                    }
14312                    pw.print("   Tuning: ");
14313                    pw.print(ActivityManager.staticGetMemoryClass());
14314                    pw.print(" (large ");
14315                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14316                    pw.print("), oom ");
14317                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14318                    pw.print(" kB");
14319                    pw.print(", restore limit ");
14320                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14321                    pw.print(" kB");
14322                    if (ActivityManager.isLowRamDeviceStatic()) {
14323                        pw.print(" (low-ram)");
14324                    }
14325                    if (ActivityManager.isHighEndGfx()) {
14326                        pw.print(" (high-end-gfx)");
14327                    }
14328                    pw.println();
14329                } else {
14330                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14331                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14332                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14333                    pw.print("tuning,");
14334                    pw.print(ActivityManager.staticGetMemoryClass());
14335                    pw.print(',');
14336                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14337                    pw.print(',');
14338                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14339                    if (ActivityManager.isLowRamDeviceStatic()) {
14340                        pw.print(",low-ram");
14341                    }
14342                    if (ActivityManager.isHighEndGfx()) {
14343                        pw.print(",high-end-gfx");
14344                    }
14345                    pw.println();
14346                }
14347            }
14348        }
14349    }
14350
14351    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14352            long memtrack, String name) {
14353        sb.append("  ");
14354        sb.append(ProcessList.makeOomAdjString(oomAdj));
14355        sb.append(' ');
14356        sb.append(ProcessList.makeProcStateString(procState));
14357        sb.append(' ');
14358        ProcessList.appendRamKb(sb, pss);
14359        sb.append(" kB: ");
14360        sb.append(name);
14361        if (memtrack > 0) {
14362            sb.append(" (");
14363            sb.append(memtrack);
14364            sb.append(" kB memtrack)");
14365        }
14366    }
14367
14368    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14369        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14370        sb.append(" (pid ");
14371        sb.append(mi.pid);
14372        sb.append(") ");
14373        sb.append(mi.adjType);
14374        sb.append('\n');
14375        if (mi.adjReason != null) {
14376            sb.append("                      ");
14377            sb.append(mi.adjReason);
14378            sb.append('\n');
14379        }
14380    }
14381
14382    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14383        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14384        for (int i=0, N=memInfos.size(); i<N; i++) {
14385            ProcessMemInfo mi = memInfos.get(i);
14386            infoMap.put(mi.pid, mi);
14387        }
14388        updateCpuStatsNow();
14389        long[] memtrackTmp = new long[1];
14390        synchronized (mProcessCpuTracker) {
14391            final int N = mProcessCpuTracker.countStats();
14392            for (int i=0; i<N; i++) {
14393                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14394                if (st.vsize > 0) {
14395                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14396                    if (pss > 0) {
14397                        if (infoMap.indexOfKey(st.pid) < 0) {
14398                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14399                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14400                            mi.pss = pss;
14401                            mi.memtrack = memtrackTmp[0];
14402                            memInfos.add(mi);
14403                        }
14404                    }
14405                }
14406            }
14407        }
14408
14409        long totalPss = 0;
14410        long totalMemtrack = 0;
14411        for (int i=0, N=memInfos.size(); i<N; i++) {
14412            ProcessMemInfo mi = memInfos.get(i);
14413            if (mi.pss == 0) {
14414                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14415                mi.memtrack = memtrackTmp[0];
14416            }
14417            totalPss += mi.pss;
14418            totalMemtrack += mi.memtrack;
14419        }
14420        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14421            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14422                if (lhs.oomAdj != rhs.oomAdj) {
14423                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14424                }
14425                if (lhs.pss != rhs.pss) {
14426                    return lhs.pss < rhs.pss ? 1 : -1;
14427                }
14428                return 0;
14429            }
14430        });
14431
14432        StringBuilder tag = new StringBuilder(128);
14433        StringBuilder stack = new StringBuilder(128);
14434        tag.append("Low on memory -- ");
14435        appendMemBucket(tag, totalPss, "total", false);
14436        appendMemBucket(stack, totalPss, "total", true);
14437
14438        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14439        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14440        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14441
14442        boolean firstLine = true;
14443        int lastOomAdj = Integer.MIN_VALUE;
14444        long extraNativeRam = 0;
14445        long extraNativeMemtrack = 0;
14446        long cachedPss = 0;
14447        for (int i=0, N=memInfos.size(); i<N; i++) {
14448            ProcessMemInfo mi = memInfos.get(i);
14449
14450            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14451                cachedPss += mi.pss;
14452            }
14453
14454            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14455                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14456                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14457                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14458                if (lastOomAdj != mi.oomAdj) {
14459                    lastOomAdj = mi.oomAdj;
14460                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14461                        tag.append(" / ");
14462                    }
14463                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14464                        if (firstLine) {
14465                            stack.append(":");
14466                            firstLine = false;
14467                        }
14468                        stack.append("\n\t at ");
14469                    } else {
14470                        stack.append("$");
14471                    }
14472                } else {
14473                    tag.append(" ");
14474                    stack.append("$");
14475                }
14476                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14477                    appendMemBucket(tag, mi.pss, mi.name, false);
14478                }
14479                appendMemBucket(stack, mi.pss, mi.name, true);
14480                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14481                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14482                    stack.append("(");
14483                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14484                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14485                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14486                            stack.append(":");
14487                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14488                        }
14489                    }
14490                    stack.append(")");
14491                }
14492            }
14493
14494            appendMemInfo(fullNativeBuilder, mi);
14495            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14496                // The short form only has native processes that are >= 512K.
14497                if (mi.pss >= 512) {
14498                    appendMemInfo(shortNativeBuilder, mi);
14499                } else {
14500                    extraNativeRam += mi.pss;
14501                    extraNativeMemtrack += mi.memtrack;
14502                }
14503            } else {
14504                // Short form has all other details, but if we have collected RAM
14505                // from smaller native processes let's dump a summary of that.
14506                if (extraNativeRam > 0) {
14507                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14508                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14509                    shortNativeBuilder.append('\n');
14510                    extraNativeRam = 0;
14511                }
14512                appendMemInfo(fullJavaBuilder, mi);
14513            }
14514        }
14515
14516        fullJavaBuilder.append("           ");
14517        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14518        fullJavaBuilder.append(" kB: TOTAL");
14519        if (totalMemtrack > 0) {
14520            fullJavaBuilder.append(" (");
14521            fullJavaBuilder.append(totalMemtrack);
14522            fullJavaBuilder.append(" kB memtrack)");
14523        } else {
14524        }
14525        fullJavaBuilder.append("\n");
14526
14527        MemInfoReader memInfo = new MemInfoReader();
14528        memInfo.readMemInfo();
14529        final long[] infos = memInfo.getRawInfo();
14530
14531        StringBuilder memInfoBuilder = new StringBuilder(1024);
14532        Debug.getMemInfo(infos);
14533        memInfoBuilder.append("  MemInfo: ");
14534        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14535        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14536        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14537        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14538        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14539        memInfoBuilder.append("           ");
14540        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14541        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14542        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14543        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14544        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14545            memInfoBuilder.append("  ZRAM: ");
14546            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14547            memInfoBuilder.append(" kB RAM, ");
14548            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14549            memInfoBuilder.append(" kB swap total, ");
14550            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14551            memInfoBuilder.append(" kB swap free\n");
14552        }
14553        final long[] ksm = getKsmInfo();
14554        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14555                || ksm[KSM_VOLATILE] != 0) {
14556            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14557            memInfoBuilder.append(" kB saved from shared ");
14558            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14559            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14560            memInfoBuilder.append(" kB unshared; ");
14561            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14562        }
14563        memInfoBuilder.append("  Free RAM: ");
14564        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14565                + memInfo.getFreeSizeKb());
14566        memInfoBuilder.append(" kB\n");
14567        memInfoBuilder.append("  Used RAM: ");
14568        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14569        memInfoBuilder.append(" kB\n");
14570        memInfoBuilder.append("  Lost RAM: ");
14571        memInfoBuilder.append(memInfo.getTotalSizeKb()
14572                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14573                - memInfo.getKernelUsedSizeKb());
14574        memInfoBuilder.append(" kB\n");
14575        Slog.i(TAG, "Low on memory:");
14576        Slog.i(TAG, shortNativeBuilder.toString());
14577        Slog.i(TAG, fullJavaBuilder.toString());
14578        Slog.i(TAG, memInfoBuilder.toString());
14579
14580        StringBuilder dropBuilder = new StringBuilder(1024);
14581        /*
14582        StringWriter oomSw = new StringWriter();
14583        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14584        StringWriter catSw = new StringWriter();
14585        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14586        String[] emptyArgs = new String[] { };
14587        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14588        oomPw.flush();
14589        String oomString = oomSw.toString();
14590        */
14591        dropBuilder.append("Low on memory:");
14592        dropBuilder.append(stack);
14593        dropBuilder.append('\n');
14594        dropBuilder.append(fullNativeBuilder);
14595        dropBuilder.append(fullJavaBuilder);
14596        dropBuilder.append('\n');
14597        dropBuilder.append(memInfoBuilder);
14598        dropBuilder.append('\n');
14599        /*
14600        dropBuilder.append(oomString);
14601        dropBuilder.append('\n');
14602        */
14603        StringWriter catSw = new StringWriter();
14604        synchronized (ActivityManagerService.this) {
14605            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14606            String[] emptyArgs = new String[] { };
14607            catPw.println();
14608            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14609            catPw.println();
14610            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14611                    false, false, null);
14612            catPw.println();
14613            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14614            catPw.flush();
14615        }
14616        dropBuilder.append(catSw.toString());
14617        addErrorToDropBox("lowmem", null, "system_server", null,
14618                null, tag.toString(), dropBuilder.toString(), null, null);
14619        //Slog.i(TAG, "Sent to dropbox:");
14620        //Slog.i(TAG, dropBuilder.toString());
14621        synchronized (ActivityManagerService.this) {
14622            long now = SystemClock.uptimeMillis();
14623            if (mLastMemUsageReportTime < now) {
14624                mLastMemUsageReportTime = now;
14625            }
14626        }
14627    }
14628
14629    /**
14630     * Searches array of arguments for the specified string
14631     * @param args array of argument strings
14632     * @param value value to search for
14633     * @return true if the value is contained in the array
14634     */
14635    private static boolean scanArgs(String[] args, String value) {
14636        if (args != null) {
14637            for (String arg : args) {
14638                if (value.equals(arg)) {
14639                    return true;
14640                }
14641            }
14642        }
14643        return false;
14644    }
14645
14646    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14647            ContentProviderRecord cpr, boolean always) {
14648        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14649
14650        if (!inLaunching || always) {
14651            synchronized (cpr) {
14652                cpr.launchingApp = null;
14653                cpr.notifyAll();
14654            }
14655            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14656            String names[] = cpr.info.authority.split(";");
14657            for (int j = 0; j < names.length; j++) {
14658                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14659            }
14660        }
14661
14662        for (int i=0; i<cpr.connections.size(); i++) {
14663            ContentProviderConnection conn = cpr.connections.get(i);
14664            if (conn.waiting) {
14665                // If this connection is waiting for the provider, then we don't
14666                // need to mess with its process unless we are always removing
14667                // or for some reason the provider is not currently launching.
14668                if (inLaunching && !always) {
14669                    continue;
14670                }
14671            }
14672            ProcessRecord capp = conn.client;
14673            conn.dead = true;
14674            if (conn.stableCount > 0) {
14675                if (!capp.persistent && capp.thread != null
14676                        && capp.pid != 0
14677                        && capp.pid != MY_PID) {
14678                    capp.kill("depends on provider "
14679                            + cpr.name.flattenToShortString()
14680                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14681                }
14682            } else if (capp.thread != null && conn.provider.provider != null) {
14683                try {
14684                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14685                } catch (RemoteException e) {
14686                }
14687                // In the protocol here, we don't expect the client to correctly
14688                // clean up this connection, we'll just remove it.
14689                cpr.connections.remove(i);
14690                conn.client.conProviders.remove(conn);
14691            }
14692        }
14693
14694        if (inLaunching && always) {
14695            mLaunchingProviders.remove(cpr);
14696        }
14697        return inLaunching;
14698    }
14699
14700    /**
14701     * Main code for cleaning up a process when it has gone away.  This is
14702     * called both as a result of the process dying, or directly when stopping
14703     * a process when running in single process mode.
14704     *
14705     * @return Returns true if the given process has been restarted, so the
14706     * app that was passed in must remain on the process lists.
14707     */
14708    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14709            boolean restarting, boolean allowRestart, int index) {
14710        if (index >= 0) {
14711            removeLruProcessLocked(app);
14712            ProcessList.remove(app.pid);
14713        }
14714
14715        mProcessesToGc.remove(app);
14716        mPendingPssProcesses.remove(app);
14717
14718        // Dismiss any open dialogs.
14719        if (app.crashDialog != null && !app.forceCrashReport) {
14720            app.crashDialog.dismiss();
14721            app.crashDialog = null;
14722        }
14723        if (app.anrDialog != null) {
14724            app.anrDialog.dismiss();
14725            app.anrDialog = null;
14726        }
14727        if (app.waitDialog != null) {
14728            app.waitDialog.dismiss();
14729            app.waitDialog = null;
14730        }
14731
14732        app.crashing = false;
14733        app.notResponding = false;
14734
14735        app.resetPackageList(mProcessStats);
14736        app.unlinkDeathRecipient();
14737        app.makeInactive(mProcessStats);
14738        app.waitingToKill = null;
14739        app.forcingToForeground = null;
14740        updateProcessForegroundLocked(app, false, false);
14741        app.foregroundActivities = false;
14742        app.hasShownUi = false;
14743        app.treatLikeActivity = false;
14744        app.hasAboveClient = false;
14745        app.hasClientActivities = false;
14746
14747        mServices.killServicesLocked(app, allowRestart);
14748
14749        boolean restart = false;
14750
14751        // Remove published content providers.
14752        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14753            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14754            final boolean always = app.bad || !allowRestart;
14755            if (removeDyingProviderLocked(app, cpr, always) || always) {
14756                // We left the provider in the launching list, need to
14757                // restart it.
14758                restart = true;
14759            }
14760
14761            cpr.provider = null;
14762            cpr.proc = null;
14763        }
14764        app.pubProviders.clear();
14765
14766        // Take care of any launching providers waiting for this process.
14767        if (checkAppInLaunchingProvidersLocked(app, false)) {
14768            restart = true;
14769        }
14770
14771        // Unregister from connected content providers.
14772        if (!app.conProviders.isEmpty()) {
14773            for (int i=0; i<app.conProviders.size(); i++) {
14774                ContentProviderConnection conn = app.conProviders.get(i);
14775                conn.provider.connections.remove(conn);
14776            }
14777            app.conProviders.clear();
14778        }
14779
14780        // At this point there may be remaining entries in mLaunchingProviders
14781        // where we were the only one waiting, so they are no longer of use.
14782        // Look for these and clean up if found.
14783        // XXX Commented out for now.  Trying to figure out a way to reproduce
14784        // the actual situation to identify what is actually going on.
14785        if (false) {
14786            for (int i=0; i<mLaunchingProviders.size(); i++) {
14787                ContentProviderRecord cpr = (ContentProviderRecord)
14788                        mLaunchingProviders.get(i);
14789                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14790                    synchronized (cpr) {
14791                        cpr.launchingApp = null;
14792                        cpr.notifyAll();
14793                    }
14794                }
14795            }
14796        }
14797
14798        skipCurrentReceiverLocked(app);
14799
14800        // Unregister any receivers.
14801        for (int i=app.receivers.size()-1; i>=0; i--) {
14802            removeReceiverLocked(app.receivers.valueAt(i));
14803        }
14804        app.receivers.clear();
14805
14806        // If the app is undergoing backup, tell the backup manager about it
14807        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14808            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14809                    + mBackupTarget.appInfo + " died during backup");
14810            try {
14811                IBackupManager bm = IBackupManager.Stub.asInterface(
14812                        ServiceManager.getService(Context.BACKUP_SERVICE));
14813                bm.agentDisconnected(app.info.packageName);
14814            } catch (RemoteException e) {
14815                // can't happen; backup manager is local
14816            }
14817        }
14818
14819        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14820            ProcessChangeItem item = mPendingProcessChanges.get(i);
14821            if (item.pid == app.pid) {
14822                mPendingProcessChanges.remove(i);
14823                mAvailProcessChanges.add(item);
14824            }
14825        }
14826        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14827
14828        // If the caller is restarting this app, then leave it in its
14829        // current lists and let the caller take care of it.
14830        if (restarting) {
14831            return false;
14832        }
14833
14834        if (!app.persistent || app.isolated) {
14835            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14836                    "Removing non-persistent process during cleanup: " + app);
14837            mProcessNames.remove(app.processName, app.uid);
14838            mIsolatedProcesses.remove(app.uid);
14839            if (mHeavyWeightProcess == app) {
14840                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14841                        mHeavyWeightProcess.userId, 0));
14842                mHeavyWeightProcess = null;
14843            }
14844        } else if (!app.removed) {
14845            // This app is persistent, so we need to keep its record around.
14846            // If it is not already on the pending app list, add it there
14847            // and start a new process for it.
14848            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14849                mPersistentStartingProcesses.add(app);
14850                restart = true;
14851            }
14852        }
14853        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14854                "Clean-up removing on hold: " + app);
14855        mProcessesOnHold.remove(app);
14856
14857        if (app == mHomeProcess) {
14858            mHomeProcess = null;
14859        }
14860        if (app == mPreviousProcess) {
14861            mPreviousProcess = null;
14862        }
14863
14864        if (restart && !app.isolated) {
14865            // We have components that still need to be running in the
14866            // process, so re-launch it.
14867            if (index < 0) {
14868                ProcessList.remove(app.pid);
14869            }
14870            mProcessNames.put(app.processName, app.uid, app);
14871            startProcessLocked(app, "restart", app.processName);
14872            return true;
14873        } else if (app.pid > 0 && app.pid != MY_PID) {
14874            // Goodbye!
14875            boolean removed;
14876            synchronized (mPidsSelfLocked) {
14877                mPidsSelfLocked.remove(app.pid);
14878                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14879            }
14880            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14881            if (app.isolated) {
14882                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14883            }
14884            app.setPid(0);
14885        }
14886        return false;
14887    }
14888
14889    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14890        // Look through the content providers we are waiting to have launched,
14891        // and if any run in this process then either schedule a restart of
14892        // the process or kill the client waiting for it if this process has
14893        // gone bad.
14894        int NL = mLaunchingProviders.size();
14895        boolean restart = false;
14896        for (int i=0; i<NL; i++) {
14897            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14898            if (cpr.launchingApp == app) {
14899                if (!alwaysBad && !app.bad) {
14900                    restart = true;
14901                } else {
14902                    removeDyingProviderLocked(app, cpr, true);
14903                    // cpr should have been removed from mLaunchingProviders
14904                    NL = mLaunchingProviders.size();
14905                    i--;
14906                }
14907            }
14908        }
14909        return restart;
14910    }
14911
14912    // =========================================================
14913    // SERVICES
14914    // =========================================================
14915
14916    @Override
14917    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14918            int flags) {
14919        enforceNotIsolatedCaller("getServices");
14920        synchronized (this) {
14921            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14922        }
14923    }
14924
14925    @Override
14926    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14927        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14928        synchronized (this) {
14929            return mServices.getRunningServiceControlPanelLocked(name);
14930        }
14931    }
14932
14933    @Override
14934    public ComponentName startService(IApplicationThread caller, Intent service,
14935            String resolvedType, int userId) {
14936        enforceNotIsolatedCaller("startService");
14937        // Refuse possible leaked file descriptors
14938        if (service != null && service.hasFileDescriptors() == true) {
14939            throw new IllegalArgumentException("File descriptors passed in Intent");
14940        }
14941
14942        if (DEBUG_SERVICE)
14943            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14944        synchronized(this) {
14945            final int callingPid = Binder.getCallingPid();
14946            final int callingUid = Binder.getCallingUid();
14947            final long origId = Binder.clearCallingIdentity();
14948            ComponentName res = mServices.startServiceLocked(caller, service,
14949                    resolvedType, callingPid, callingUid, userId);
14950            Binder.restoreCallingIdentity(origId);
14951            return res;
14952        }
14953    }
14954
14955    ComponentName startServiceInPackage(int uid,
14956            Intent service, String resolvedType, int userId) {
14957        synchronized(this) {
14958            if (DEBUG_SERVICE)
14959                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14960            final long origId = Binder.clearCallingIdentity();
14961            ComponentName res = mServices.startServiceLocked(null, service,
14962                    resolvedType, -1, uid, userId);
14963            Binder.restoreCallingIdentity(origId);
14964            return res;
14965        }
14966    }
14967
14968    @Override
14969    public int stopService(IApplicationThread caller, Intent service,
14970            String resolvedType, int userId) {
14971        enforceNotIsolatedCaller("stopService");
14972        // Refuse possible leaked file descriptors
14973        if (service != null && service.hasFileDescriptors() == true) {
14974            throw new IllegalArgumentException("File descriptors passed in Intent");
14975        }
14976
14977        synchronized(this) {
14978            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14979        }
14980    }
14981
14982    @Override
14983    public IBinder peekService(Intent service, String resolvedType) {
14984        enforceNotIsolatedCaller("peekService");
14985        // Refuse possible leaked file descriptors
14986        if (service != null && service.hasFileDescriptors() == true) {
14987            throw new IllegalArgumentException("File descriptors passed in Intent");
14988        }
14989        synchronized(this) {
14990            return mServices.peekServiceLocked(service, resolvedType);
14991        }
14992    }
14993
14994    @Override
14995    public boolean stopServiceToken(ComponentName className, IBinder token,
14996            int startId) {
14997        synchronized(this) {
14998            return mServices.stopServiceTokenLocked(className, token, startId);
14999        }
15000    }
15001
15002    @Override
15003    public void setServiceForeground(ComponentName className, IBinder token,
15004            int id, Notification notification, boolean removeNotification) {
15005        synchronized(this) {
15006            mServices.setServiceForegroundLocked(className, token, id, notification,
15007                    removeNotification);
15008        }
15009    }
15010
15011    @Override
15012    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15013            boolean requireFull, String name, String callerPackage) {
15014        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15015                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15016    }
15017
15018    int unsafeConvertIncomingUser(int userId) {
15019        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15020                ? mCurrentUserId : userId;
15021    }
15022
15023    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15024            int allowMode, String name, String callerPackage) {
15025        final int callingUserId = UserHandle.getUserId(callingUid);
15026        if (callingUserId == userId) {
15027            return userId;
15028        }
15029
15030        // Note that we may be accessing mCurrentUserId outside of a lock...
15031        // shouldn't be a big deal, if this is being called outside
15032        // of a locked context there is intrinsically a race with
15033        // the value the caller will receive and someone else changing it.
15034        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15035        // we will switch to the calling user if access to the current user fails.
15036        int targetUserId = unsafeConvertIncomingUser(userId);
15037
15038        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15039            final boolean allow;
15040            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15041                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15042                // If the caller has this permission, they always pass go.  And collect $200.
15043                allow = true;
15044            } else if (allowMode == ALLOW_FULL_ONLY) {
15045                // We require full access, sucks to be you.
15046                allow = false;
15047            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15048                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15049                // If the caller does not have either permission, they are always doomed.
15050                allow = false;
15051            } else if (allowMode == ALLOW_NON_FULL) {
15052                // We are blanket allowing non-full access, you lucky caller!
15053                allow = true;
15054            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15055                // We may or may not allow this depending on whether the two users are
15056                // in the same profile.
15057                synchronized (mUserProfileGroupIdsSelfLocked) {
15058                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15059                            UserInfo.NO_PROFILE_GROUP_ID);
15060                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15061                            UserInfo.NO_PROFILE_GROUP_ID);
15062                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15063                            && callingProfile == targetProfile;
15064                }
15065            } else {
15066                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15067            }
15068            if (!allow) {
15069                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15070                    // In this case, they would like to just execute as their
15071                    // owner user instead of failing.
15072                    targetUserId = callingUserId;
15073                } else {
15074                    StringBuilder builder = new StringBuilder(128);
15075                    builder.append("Permission Denial: ");
15076                    builder.append(name);
15077                    if (callerPackage != null) {
15078                        builder.append(" from ");
15079                        builder.append(callerPackage);
15080                    }
15081                    builder.append(" asks to run as user ");
15082                    builder.append(userId);
15083                    builder.append(" but is calling from user ");
15084                    builder.append(UserHandle.getUserId(callingUid));
15085                    builder.append("; this requires ");
15086                    builder.append(INTERACT_ACROSS_USERS_FULL);
15087                    if (allowMode != ALLOW_FULL_ONLY) {
15088                        builder.append(" or ");
15089                        builder.append(INTERACT_ACROSS_USERS);
15090                    }
15091                    String msg = builder.toString();
15092                    Slog.w(TAG, msg);
15093                    throw new SecurityException(msg);
15094                }
15095            }
15096        }
15097        if (!allowAll && targetUserId < 0) {
15098            throw new IllegalArgumentException(
15099                    "Call does not support special user #" + targetUserId);
15100        }
15101        // Check shell permission
15102        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15103            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15104                    targetUserId)) {
15105                throw new SecurityException("Shell does not have permission to access user "
15106                        + targetUserId + "\n " + Debug.getCallers(3));
15107            }
15108        }
15109        return targetUserId;
15110    }
15111
15112    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15113            String className, int flags) {
15114        boolean result = false;
15115        // For apps that don't have pre-defined UIDs, check for permission
15116        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15117            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15118                if (ActivityManager.checkUidPermission(
15119                        INTERACT_ACROSS_USERS,
15120                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15121                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15122                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15123                            + " requests FLAG_SINGLE_USER, but app does not hold "
15124                            + INTERACT_ACROSS_USERS;
15125                    Slog.w(TAG, msg);
15126                    throw new SecurityException(msg);
15127                }
15128                // Permission passed
15129                result = true;
15130            }
15131        } else if ("system".equals(componentProcessName)) {
15132            result = true;
15133        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15134            // Phone app and persistent apps are allowed to export singleuser providers.
15135            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15136                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15137        }
15138        if (DEBUG_MU) {
15139            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15140                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15141        }
15142        return result;
15143    }
15144
15145    /**
15146     * Checks to see if the caller is in the same app as the singleton
15147     * component, or the component is in a special app. It allows special apps
15148     * to export singleton components but prevents exporting singleton
15149     * components for regular apps.
15150     */
15151    boolean isValidSingletonCall(int callingUid, int componentUid) {
15152        int componentAppId = UserHandle.getAppId(componentUid);
15153        return UserHandle.isSameApp(callingUid, componentUid)
15154                || componentAppId == Process.SYSTEM_UID
15155                || componentAppId == Process.PHONE_UID
15156                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15157                        == PackageManager.PERMISSION_GRANTED;
15158    }
15159
15160    public int bindService(IApplicationThread caller, IBinder token,
15161            Intent service, String resolvedType,
15162            IServiceConnection connection, int flags, int userId) {
15163        enforceNotIsolatedCaller("bindService");
15164
15165        // Refuse possible leaked file descriptors
15166        if (service != null && service.hasFileDescriptors() == true) {
15167            throw new IllegalArgumentException("File descriptors passed in Intent");
15168        }
15169
15170        synchronized(this) {
15171            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15172                    connection, flags, userId);
15173        }
15174    }
15175
15176    public boolean unbindService(IServiceConnection connection) {
15177        synchronized (this) {
15178            return mServices.unbindServiceLocked(connection);
15179        }
15180    }
15181
15182    public void publishService(IBinder token, Intent intent, IBinder service) {
15183        // Refuse possible leaked file descriptors
15184        if (intent != null && intent.hasFileDescriptors() == true) {
15185            throw new IllegalArgumentException("File descriptors passed in Intent");
15186        }
15187
15188        synchronized(this) {
15189            if (!(token instanceof ServiceRecord)) {
15190                throw new IllegalArgumentException("Invalid service token");
15191            }
15192            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15193        }
15194    }
15195
15196    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15197        // Refuse possible leaked file descriptors
15198        if (intent != null && intent.hasFileDescriptors() == true) {
15199            throw new IllegalArgumentException("File descriptors passed in Intent");
15200        }
15201
15202        synchronized(this) {
15203            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15204        }
15205    }
15206
15207    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15208        synchronized(this) {
15209            if (!(token instanceof ServiceRecord)) {
15210                throw new IllegalArgumentException("Invalid service token");
15211            }
15212            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15213        }
15214    }
15215
15216    // =========================================================
15217    // BACKUP AND RESTORE
15218    // =========================================================
15219
15220    // Cause the target app to be launched if necessary and its backup agent
15221    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15222    // activity manager to announce its creation.
15223    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15224        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15225        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15226
15227        synchronized(this) {
15228            // !!! TODO: currently no check here that we're already bound
15229            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15230            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15231            synchronized (stats) {
15232                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15233            }
15234
15235            // Backup agent is now in use, its package can't be stopped.
15236            try {
15237                AppGlobals.getPackageManager().setPackageStoppedState(
15238                        app.packageName, false, UserHandle.getUserId(app.uid));
15239            } catch (RemoteException e) {
15240            } catch (IllegalArgumentException e) {
15241                Slog.w(TAG, "Failed trying to unstop package "
15242                        + app.packageName + ": " + e);
15243            }
15244
15245            BackupRecord r = new BackupRecord(ss, app, backupMode);
15246            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15247                    ? new ComponentName(app.packageName, app.backupAgentName)
15248                    : new ComponentName("android", "FullBackupAgent");
15249            // startProcessLocked() returns existing proc's record if it's already running
15250            ProcessRecord proc = startProcessLocked(app.processName, app,
15251                    false, 0, "backup", hostingName, false, false, false);
15252            if (proc == null) {
15253                Slog.e(TAG, "Unable to start backup agent process " + r);
15254                return false;
15255            }
15256
15257            r.app = proc;
15258            mBackupTarget = r;
15259            mBackupAppName = app.packageName;
15260
15261            // Try not to kill the process during backup
15262            updateOomAdjLocked(proc);
15263
15264            // If the process is already attached, schedule the creation of the backup agent now.
15265            // If it is not yet live, this will be done when it attaches to the framework.
15266            if (proc.thread != null) {
15267                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15268                try {
15269                    proc.thread.scheduleCreateBackupAgent(app,
15270                            compatibilityInfoForPackageLocked(app), backupMode);
15271                } catch (RemoteException e) {
15272                    // Will time out on the backup manager side
15273                }
15274            } else {
15275                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15276            }
15277            // Invariants: at this point, the target app process exists and the application
15278            // is either already running or in the process of coming up.  mBackupTarget and
15279            // mBackupAppName describe the app, so that when it binds back to the AM we
15280            // know that it's scheduled for a backup-agent operation.
15281        }
15282
15283        return true;
15284    }
15285
15286    @Override
15287    public void clearPendingBackup() {
15288        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15289        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15290
15291        synchronized (this) {
15292            mBackupTarget = null;
15293            mBackupAppName = null;
15294        }
15295    }
15296
15297    // A backup agent has just come up
15298    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15299        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15300                + " = " + agent);
15301
15302        synchronized(this) {
15303            if (!agentPackageName.equals(mBackupAppName)) {
15304                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15305                return;
15306            }
15307        }
15308
15309        long oldIdent = Binder.clearCallingIdentity();
15310        try {
15311            IBackupManager bm = IBackupManager.Stub.asInterface(
15312                    ServiceManager.getService(Context.BACKUP_SERVICE));
15313            bm.agentConnected(agentPackageName, agent);
15314        } catch (RemoteException e) {
15315            // can't happen; the backup manager service is local
15316        } catch (Exception e) {
15317            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15318            e.printStackTrace();
15319        } finally {
15320            Binder.restoreCallingIdentity(oldIdent);
15321        }
15322    }
15323
15324    // done with this agent
15325    public void unbindBackupAgent(ApplicationInfo appInfo) {
15326        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15327        if (appInfo == null) {
15328            Slog.w(TAG, "unbind backup agent for null app");
15329            return;
15330        }
15331
15332        synchronized(this) {
15333            try {
15334                if (mBackupAppName == null) {
15335                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15336                    return;
15337                }
15338
15339                if (!mBackupAppName.equals(appInfo.packageName)) {
15340                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15341                    return;
15342                }
15343
15344                // Not backing this app up any more; reset its OOM adjustment
15345                final ProcessRecord proc = mBackupTarget.app;
15346                updateOomAdjLocked(proc);
15347
15348                // If the app crashed during backup, 'thread' will be null here
15349                if (proc.thread != null) {
15350                    try {
15351                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15352                                compatibilityInfoForPackageLocked(appInfo));
15353                    } catch (Exception e) {
15354                        Slog.e(TAG, "Exception when unbinding backup agent:");
15355                        e.printStackTrace();
15356                    }
15357                }
15358            } finally {
15359                mBackupTarget = null;
15360                mBackupAppName = null;
15361            }
15362        }
15363    }
15364    // =========================================================
15365    // BROADCASTS
15366    // =========================================================
15367
15368    private final List getStickiesLocked(String action, IntentFilter filter,
15369            List cur, int userId) {
15370        final ContentResolver resolver = mContext.getContentResolver();
15371        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15372        if (stickies == null) {
15373            return cur;
15374        }
15375        final ArrayList<Intent> list = stickies.get(action);
15376        if (list == null) {
15377            return cur;
15378        }
15379        int N = list.size();
15380        for (int i=0; i<N; i++) {
15381            Intent intent = list.get(i);
15382            if (filter.match(resolver, intent, true, TAG) >= 0) {
15383                if (cur == null) {
15384                    cur = new ArrayList<Intent>();
15385                }
15386                cur.add(intent);
15387            }
15388        }
15389        return cur;
15390    }
15391
15392    boolean isPendingBroadcastProcessLocked(int pid) {
15393        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15394                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15395    }
15396
15397    void skipPendingBroadcastLocked(int pid) {
15398            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15399            for (BroadcastQueue queue : mBroadcastQueues) {
15400                queue.skipPendingBroadcastLocked(pid);
15401            }
15402    }
15403
15404    // The app just attached; send any pending broadcasts that it should receive
15405    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15406        boolean didSomething = false;
15407        for (BroadcastQueue queue : mBroadcastQueues) {
15408            didSomething |= queue.sendPendingBroadcastsLocked(app);
15409        }
15410        return didSomething;
15411    }
15412
15413    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15414            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15415        enforceNotIsolatedCaller("registerReceiver");
15416        int callingUid;
15417        int callingPid;
15418        synchronized(this) {
15419            ProcessRecord callerApp = null;
15420            if (caller != null) {
15421                callerApp = getRecordForAppLocked(caller);
15422                if (callerApp == null) {
15423                    throw new SecurityException(
15424                            "Unable to find app for caller " + caller
15425                            + " (pid=" + Binder.getCallingPid()
15426                            + ") when registering receiver " + receiver);
15427                }
15428                if (callerApp.info.uid != Process.SYSTEM_UID &&
15429                        !callerApp.pkgList.containsKey(callerPackage) &&
15430                        !"android".equals(callerPackage)) {
15431                    throw new SecurityException("Given caller package " + callerPackage
15432                            + " is not running in process " + callerApp);
15433                }
15434                callingUid = callerApp.info.uid;
15435                callingPid = callerApp.pid;
15436            } else {
15437                callerPackage = null;
15438                callingUid = Binder.getCallingUid();
15439                callingPid = Binder.getCallingPid();
15440            }
15441
15442            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15443                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15444
15445            List allSticky = null;
15446
15447            // Look for any matching sticky broadcasts...
15448            Iterator actions = filter.actionsIterator();
15449            if (actions != null) {
15450                while (actions.hasNext()) {
15451                    String action = (String)actions.next();
15452                    allSticky = getStickiesLocked(action, filter, allSticky,
15453                            UserHandle.USER_ALL);
15454                    allSticky = getStickiesLocked(action, filter, allSticky,
15455                            UserHandle.getUserId(callingUid));
15456                }
15457            } else {
15458                allSticky = getStickiesLocked(null, filter, allSticky,
15459                        UserHandle.USER_ALL);
15460                allSticky = getStickiesLocked(null, filter, allSticky,
15461                        UserHandle.getUserId(callingUid));
15462            }
15463
15464            // The first sticky in the list is returned directly back to
15465            // the client.
15466            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15467
15468            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15469                    + ": " + sticky);
15470
15471            if (receiver == null) {
15472                return sticky;
15473            }
15474
15475            ReceiverList rl
15476                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15477            if (rl == null) {
15478                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15479                        userId, receiver);
15480                if (rl.app != null) {
15481                    rl.app.receivers.add(rl);
15482                } else {
15483                    try {
15484                        receiver.asBinder().linkToDeath(rl, 0);
15485                    } catch (RemoteException e) {
15486                        return sticky;
15487                    }
15488                    rl.linkedToDeath = true;
15489                }
15490                mRegisteredReceivers.put(receiver.asBinder(), rl);
15491            } else if (rl.uid != callingUid) {
15492                throw new IllegalArgumentException(
15493                        "Receiver requested to register for uid " + callingUid
15494                        + " was previously registered for uid " + rl.uid);
15495            } else if (rl.pid != callingPid) {
15496                throw new IllegalArgumentException(
15497                        "Receiver requested to register for pid " + callingPid
15498                        + " was previously registered for pid " + rl.pid);
15499            } else if (rl.userId != userId) {
15500                throw new IllegalArgumentException(
15501                        "Receiver requested to register for user " + userId
15502                        + " was previously registered for user " + rl.userId);
15503            }
15504            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15505                    permission, callingUid, userId);
15506            rl.add(bf);
15507            if (!bf.debugCheck()) {
15508                Slog.w(TAG, "==> For Dynamic broadast");
15509            }
15510            mReceiverResolver.addFilter(bf);
15511
15512            // Enqueue broadcasts for all existing stickies that match
15513            // this filter.
15514            if (allSticky != null) {
15515                ArrayList receivers = new ArrayList();
15516                receivers.add(bf);
15517
15518                int N = allSticky.size();
15519                for (int i=0; i<N; i++) {
15520                    Intent intent = (Intent)allSticky.get(i);
15521                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15522                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15523                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15524                            null, null, false, true, true, -1);
15525                    queue.enqueueParallelBroadcastLocked(r);
15526                    queue.scheduleBroadcastsLocked();
15527                }
15528            }
15529
15530            return sticky;
15531        }
15532    }
15533
15534    public void unregisterReceiver(IIntentReceiver receiver) {
15535        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15536
15537        final long origId = Binder.clearCallingIdentity();
15538        try {
15539            boolean doTrim = false;
15540
15541            synchronized(this) {
15542                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15543                if (rl != null) {
15544                    if (rl.curBroadcast != null) {
15545                        BroadcastRecord r = rl.curBroadcast;
15546                        final boolean doNext = finishReceiverLocked(
15547                                receiver.asBinder(), r.resultCode, r.resultData,
15548                                r.resultExtras, r.resultAbort);
15549                        if (doNext) {
15550                            doTrim = true;
15551                            r.queue.processNextBroadcast(false);
15552                        }
15553                    }
15554
15555                    if (rl.app != null) {
15556                        rl.app.receivers.remove(rl);
15557                    }
15558                    removeReceiverLocked(rl);
15559                    if (rl.linkedToDeath) {
15560                        rl.linkedToDeath = false;
15561                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15562                    }
15563                }
15564            }
15565
15566            // If we actually concluded any broadcasts, we might now be able
15567            // to trim the recipients' apps from our working set
15568            if (doTrim) {
15569                trimApplications();
15570                return;
15571            }
15572
15573        } finally {
15574            Binder.restoreCallingIdentity(origId);
15575        }
15576    }
15577
15578    void removeReceiverLocked(ReceiverList rl) {
15579        mRegisteredReceivers.remove(rl.receiver.asBinder());
15580        int N = rl.size();
15581        for (int i=0; i<N; i++) {
15582            mReceiverResolver.removeFilter(rl.get(i));
15583        }
15584    }
15585
15586    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15587        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15588            ProcessRecord r = mLruProcesses.get(i);
15589            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15590                try {
15591                    r.thread.dispatchPackageBroadcast(cmd, packages);
15592                } catch (RemoteException ex) {
15593                }
15594            }
15595        }
15596    }
15597
15598    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15599            int callingUid, int[] users) {
15600        List<ResolveInfo> receivers = null;
15601        try {
15602            HashSet<ComponentName> singleUserReceivers = null;
15603            boolean scannedFirstReceivers = false;
15604            for (int user : users) {
15605                // Skip users that have Shell restrictions
15606                if (callingUid == Process.SHELL_UID
15607                        && getUserManagerLocked().hasUserRestriction(
15608                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15609                    continue;
15610                }
15611                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15612                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15613                if (user != 0 && newReceivers != null) {
15614                    // If this is not the primary user, we need to check for
15615                    // any receivers that should be filtered out.
15616                    for (int i=0; i<newReceivers.size(); i++) {
15617                        ResolveInfo ri = newReceivers.get(i);
15618                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15619                            newReceivers.remove(i);
15620                            i--;
15621                        }
15622                    }
15623                }
15624                if (newReceivers != null && newReceivers.size() == 0) {
15625                    newReceivers = null;
15626                }
15627                if (receivers == null) {
15628                    receivers = newReceivers;
15629                } else if (newReceivers != null) {
15630                    // We need to concatenate the additional receivers
15631                    // found with what we have do far.  This would be easy,
15632                    // but we also need to de-dup any receivers that are
15633                    // singleUser.
15634                    if (!scannedFirstReceivers) {
15635                        // Collect any single user receivers we had already retrieved.
15636                        scannedFirstReceivers = true;
15637                        for (int i=0; i<receivers.size(); i++) {
15638                            ResolveInfo ri = receivers.get(i);
15639                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15640                                ComponentName cn = new ComponentName(
15641                                        ri.activityInfo.packageName, ri.activityInfo.name);
15642                                if (singleUserReceivers == null) {
15643                                    singleUserReceivers = new HashSet<ComponentName>();
15644                                }
15645                                singleUserReceivers.add(cn);
15646                            }
15647                        }
15648                    }
15649                    // Add the new results to the existing results, tracking
15650                    // and de-dupping single user receivers.
15651                    for (int i=0; i<newReceivers.size(); i++) {
15652                        ResolveInfo ri = newReceivers.get(i);
15653                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15654                            ComponentName cn = new ComponentName(
15655                                    ri.activityInfo.packageName, ri.activityInfo.name);
15656                            if (singleUserReceivers == null) {
15657                                singleUserReceivers = new HashSet<ComponentName>();
15658                            }
15659                            if (!singleUserReceivers.contains(cn)) {
15660                                singleUserReceivers.add(cn);
15661                                receivers.add(ri);
15662                            }
15663                        } else {
15664                            receivers.add(ri);
15665                        }
15666                    }
15667                }
15668            }
15669        } catch (RemoteException ex) {
15670            // pm is in same process, this will never happen.
15671        }
15672        return receivers;
15673    }
15674
15675    private final int broadcastIntentLocked(ProcessRecord callerApp,
15676            String callerPackage, Intent intent, String resolvedType,
15677            IIntentReceiver resultTo, int resultCode, String resultData,
15678            Bundle map, String requiredPermission, int appOp,
15679            boolean ordered, boolean sticky, int callingPid, int callingUid,
15680            int userId) {
15681        intent = new Intent(intent);
15682
15683        // By default broadcasts do not go to stopped apps.
15684        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15685
15686        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15687            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15688            + " ordered=" + ordered + " userid=" + userId);
15689        if ((resultTo != null) && !ordered) {
15690            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15691        }
15692
15693        userId = handleIncomingUser(callingPid, callingUid, userId,
15694                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15695
15696        // Make sure that the user who is receiving this broadcast is running.
15697        // If not, we will just skip it. Make an exception for shutdown broadcasts
15698        // and upgrade steps.
15699
15700        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15701            if ((callingUid != Process.SYSTEM_UID
15702                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15703                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15704                Slog.w(TAG, "Skipping broadcast of " + intent
15705                        + ": user " + userId + " is stopped");
15706                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15707            }
15708        }
15709
15710        /*
15711         * Prevent non-system code (defined here to be non-persistent
15712         * processes) from sending protected broadcasts.
15713         */
15714        int callingAppId = UserHandle.getAppId(callingUid);
15715        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15716            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15717            || callingAppId == Process.NFC_UID || callingUid == 0) {
15718            // Always okay.
15719        } else if (callerApp == null || !callerApp.persistent) {
15720            try {
15721                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15722                        intent.getAction())) {
15723                    String msg = "Permission Denial: not allowed to send broadcast "
15724                            + intent.getAction() + " from pid="
15725                            + callingPid + ", uid=" + callingUid;
15726                    Slog.w(TAG, msg);
15727                    throw new SecurityException(msg);
15728                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15729                    // Special case for compatibility: we don't want apps to send this,
15730                    // but historically it has not been protected and apps may be using it
15731                    // to poke their own app widget.  So, instead of making it protected,
15732                    // just limit it to the caller.
15733                    if (callerApp == null) {
15734                        String msg = "Permission Denial: not allowed to send broadcast "
15735                                + intent.getAction() + " from unknown caller.";
15736                        Slog.w(TAG, msg);
15737                        throw new SecurityException(msg);
15738                    } else if (intent.getComponent() != null) {
15739                        // They are good enough to send to an explicit component...  verify
15740                        // it is being sent to the calling app.
15741                        if (!intent.getComponent().getPackageName().equals(
15742                                callerApp.info.packageName)) {
15743                            String msg = "Permission Denial: not allowed to send broadcast "
15744                                    + intent.getAction() + " to "
15745                                    + intent.getComponent().getPackageName() + " from "
15746                                    + callerApp.info.packageName;
15747                            Slog.w(TAG, msg);
15748                            throw new SecurityException(msg);
15749                        }
15750                    } else {
15751                        // Limit broadcast to their own package.
15752                        intent.setPackage(callerApp.info.packageName);
15753                    }
15754                }
15755            } catch (RemoteException e) {
15756                Slog.w(TAG, "Remote exception", e);
15757                return ActivityManager.BROADCAST_SUCCESS;
15758            }
15759        }
15760
15761        final String action = intent.getAction();
15762        if (action != null) {
15763            switch (action) {
15764                case Intent.ACTION_UID_REMOVED:
15765                case Intent.ACTION_PACKAGE_REMOVED:
15766                case Intent.ACTION_PACKAGE_CHANGED:
15767                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15768                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15769                    // Handle special intents: if this broadcast is from the package
15770                    // manager about a package being removed, we need to remove all of
15771                    // its activities from the history stack.
15772                    if (checkComponentPermission(
15773                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15774                            callingPid, callingUid, -1, true)
15775                            != PackageManager.PERMISSION_GRANTED) {
15776                        String msg = "Permission Denial: " + intent.getAction()
15777                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15778                                + ", uid=" + callingUid + ")"
15779                                + " requires "
15780                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15781                        Slog.w(TAG, msg);
15782                        throw new SecurityException(msg);
15783                    }
15784                    switch (action) {
15785                        case Intent.ACTION_UID_REMOVED:
15786                            final Bundle intentExtras = intent.getExtras();
15787                            final int uid = intentExtras != null
15788                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15789                            if (uid >= 0) {
15790                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15791                                synchronized (bs) {
15792                                    bs.removeUidStatsLocked(uid);
15793                                }
15794                                mAppOpsService.uidRemoved(uid);
15795                            }
15796                            break;
15797                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15798                            // If resources are unavailable just force stop all those packages
15799                            // and flush the attribute cache as well.
15800                            String list[] =
15801                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15802                            if (list != null && list.length > 0) {
15803                                for (int i = 0; i < list.length; i++) {
15804                                    forceStopPackageLocked(list[i], -1, false, true, true,
15805                                            false, false, userId, "storage unmount");
15806                                }
15807                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15808                                sendPackageBroadcastLocked(
15809                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15810                                        userId);
15811                            }
15812                            break;
15813                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15814                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15815                            break;
15816                        case Intent.ACTION_PACKAGE_REMOVED:
15817                        case Intent.ACTION_PACKAGE_CHANGED:
15818                            Uri data = intent.getData();
15819                            String ssp;
15820                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15821                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15822                                boolean fullUninstall = removed &&
15823                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15824                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15825                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15826                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15827                                            false, true, true, false, fullUninstall, userId,
15828                                            removed ? "pkg removed" : "pkg changed");
15829                                }
15830                                if (removed) {
15831                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15832                                            new String[] {ssp}, userId);
15833                                    if (fullUninstall) {
15834                                        mAppOpsService.packageRemoved(
15835                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15836
15837                                        // Remove all permissions granted from/to this package
15838                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15839
15840                                        removeTasksByPackageNameLocked(ssp, userId);
15841                                    }
15842                                } else {
15843                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15844                                    if (userId == UserHandle.USER_OWNER) {
15845                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15846                                    }
15847                                }
15848                            }
15849                            break;
15850                    }
15851                    break;
15852                case Intent.ACTION_PACKAGE_ADDED:
15853                    // Special case for adding a package: by default turn on compatibility mode.
15854                    Uri data = intent.getData();
15855                    String ssp;
15856                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15857                        final boolean replacing =
15858                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15859                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15860
15861                        if (replacing) {
15862                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15863                        }
15864                        if (userId == UserHandle.USER_OWNER) {
15865                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15866                        }
15867                    }
15868                    break;
15869                case Intent.ACTION_TIMEZONE_CHANGED:
15870                    // If this is the time zone changed action, queue up a message that will reset
15871                    // the timezone of all currently running processes. This message will get
15872                    // queued up before the broadcast happens.
15873                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15874                    break;
15875                case Intent.ACTION_TIME_CHANGED:
15876                    // If the user set the time, let all running processes know.
15877                    final int is24Hour =
15878                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15879                                    : 0;
15880                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15881                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15882                    synchronized (stats) {
15883                        stats.noteCurrentTimeChangedLocked();
15884                    }
15885                    break;
15886                case Intent.ACTION_CLEAR_DNS_CACHE:
15887                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15888                    break;
15889                case Proxy.PROXY_CHANGE_ACTION:
15890                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15891                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15892                    break;
15893            }
15894        }
15895
15896        // Add to the sticky list if requested.
15897        if (sticky) {
15898            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15899                    callingPid, callingUid)
15900                    != PackageManager.PERMISSION_GRANTED) {
15901                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15902                        + callingPid + ", uid=" + callingUid
15903                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15904                Slog.w(TAG, msg);
15905                throw new SecurityException(msg);
15906            }
15907            if (requiredPermission != null) {
15908                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15909                        + " and enforce permission " + requiredPermission);
15910                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15911            }
15912            if (intent.getComponent() != null) {
15913                throw new SecurityException(
15914                        "Sticky broadcasts can't target a specific component");
15915            }
15916            // We use userId directly here, since the "all" target is maintained
15917            // as a separate set of sticky broadcasts.
15918            if (userId != UserHandle.USER_ALL) {
15919                // But first, if this is not a broadcast to all users, then
15920                // make sure it doesn't conflict with an existing broadcast to
15921                // all users.
15922                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15923                        UserHandle.USER_ALL);
15924                if (stickies != null) {
15925                    ArrayList<Intent> list = stickies.get(intent.getAction());
15926                    if (list != null) {
15927                        int N = list.size();
15928                        int i;
15929                        for (i=0; i<N; i++) {
15930                            if (intent.filterEquals(list.get(i))) {
15931                                throw new IllegalArgumentException(
15932                                        "Sticky broadcast " + intent + " for user "
15933                                        + userId + " conflicts with existing global broadcast");
15934                            }
15935                        }
15936                    }
15937                }
15938            }
15939            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15940            if (stickies == null) {
15941                stickies = new ArrayMap<String, ArrayList<Intent>>();
15942                mStickyBroadcasts.put(userId, stickies);
15943            }
15944            ArrayList<Intent> list = stickies.get(intent.getAction());
15945            if (list == null) {
15946                list = new ArrayList<Intent>();
15947                stickies.put(intent.getAction(), list);
15948            }
15949            int N = list.size();
15950            int i;
15951            for (i=0; i<N; i++) {
15952                if (intent.filterEquals(list.get(i))) {
15953                    // This sticky already exists, replace it.
15954                    list.set(i, new Intent(intent));
15955                    break;
15956                }
15957            }
15958            if (i >= N) {
15959                list.add(new Intent(intent));
15960            }
15961        }
15962
15963        int[] users;
15964        if (userId == UserHandle.USER_ALL) {
15965            // Caller wants broadcast to go to all started users.
15966            users = mStartedUserArray;
15967        } else {
15968            // Caller wants broadcast to go to one specific user.
15969            users = new int[] {userId};
15970        }
15971
15972        // Figure out who all will receive this broadcast.
15973        List receivers = null;
15974        List<BroadcastFilter> registeredReceivers = null;
15975        // Need to resolve the intent to interested receivers...
15976        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15977                 == 0) {
15978            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15979        }
15980        if (intent.getComponent() == null) {
15981            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15982                // Query one target user at a time, excluding shell-restricted users
15983                UserManagerService ums = getUserManagerLocked();
15984                for (int i = 0; i < users.length; i++) {
15985                    if (ums.hasUserRestriction(
15986                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15987                        continue;
15988                    }
15989                    List<BroadcastFilter> registeredReceiversForUser =
15990                            mReceiverResolver.queryIntent(intent,
15991                                    resolvedType, false, users[i]);
15992                    if (registeredReceivers == null) {
15993                        registeredReceivers = registeredReceiversForUser;
15994                    } else if (registeredReceiversForUser != null) {
15995                        registeredReceivers.addAll(registeredReceiversForUser);
15996                    }
15997                }
15998            } else {
15999                registeredReceivers = mReceiverResolver.queryIntent(intent,
16000                        resolvedType, false, userId);
16001            }
16002        }
16003
16004        final boolean replacePending =
16005                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16006
16007        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16008                + " replacePending=" + replacePending);
16009
16010        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16011        if (!ordered && NR > 0) {
16012            // If we are not serializing this broadcast, then send the
16013            // registered receivers separately so they don't wait for the
16014            // components to be launched.
16015            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16016            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16017                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16018                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16019                    ordered, sticky, false, userId);
16020            if (DEBUG_BROADCAST) Slog.v(
16021                    TAG, "Enqueueing parallel broadcast " + r);
16022            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16023            if (!replaced) {
16024                queue.enqueueParallelBroadcastLocked(r);
16025                queue.scheduleBroadcastsLocked();
16026            }
16027            registeredReceivers = null;
16028            NR = 0;
16029        }
16030
16031        // Merge into one list.
16032        int ir = 0;
16033        if (receivers != null) {
16034            // A special case for PACKAGE_ADDED: do not allow the package
16035            // being added to see this broadcast.  This prevents them from
16036            // using this as a back door to get run as soon as they are
16037            // installed.  Maybe in the future we want to have a special install
16038            // broadcast or such for apps, but we'd like to deliberately make
16039            // this decision.
16040            String skipPackages[] = null;
16041            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16042                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16043                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16044                Uri data = intent.getData();
16045                if (data != null) {
16046                    String pkgName = data.getSchemeSpecificPart();
16047                    if (pkgName != null) {
16048                        skipPackages = new String[] { pkgName };
16049                    }
16050                }
16051            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16052                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16053            }
16054            if (skipPackages != null && (skipPackages.length > 0)) {
16055                for (String skipPackage : skipPackages) {
16056                    if (skipPackage != null) {
16057                        int NT = receivers.size();
16058                        for (int it=0; it<NT; it++) {
16059                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16060                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16061                                receivers.remove(it);
16062                                it--;
16063                                NT--;
16064                            }
16065                        }
16066                    }
16067                }
16068            }
16069
16070            int NT = receivers != null ? receivers.size() : 0;
16071            int it = 0;
16072            ResolveInfo curt = null;
16073            BroadcastFilter curr = null;
16074            while (it < NT && ir < NR) {
16075                if (curt == null) {
16076                    curt = (ResolveInfo)receivers.get(it);
16077                }
16078                if (curr == null) {
16079                    curr = registeredReceivers.get(ir);
16080                }
16081                if (curr.getPriority() >= curt.priority) {
16082                    // Insert this broadcast record into the final list.
16083                    receivers.add(it, curr);
16084                    ir++;
16085                    curr = null;
16086                    it++;
16087                    NT++;
16088                } else {
16089                    // Skip to the next ResolveInfo in the final list.
16090                    it++;
16091                    curt = null;
16092                }
16093            }
16094        }
16095        while (ir < NR) {
16096            if (receivers == null) {
16097                receivers = new ArrayList();
16098            }
16099            receivers.add(registeredReceivers.get(ir));
16100            ir++;
16101        }
16102
16103        if ((receivers != null && receivers.size() > 0)
16104                || resultTo != null) {
16105            BroadcastQueue queue = broadcastQueueForIntent(intent);
16106            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16107                    callerPackage, callingPid, callingUid, resolvedType,
16108                    requiredPermission, appOp, receivers, resultTo, resultCode,
16109                    resultData, map, ordered, sticky, false, userId);
16110            if (DEBUG_BROADCAST) Slog.v(
16111                    TAG, "Enqueueing ordered broadcast " + r
16112                    + ": prev had " + queue.mOrderedBroadcasts.size());
16113            if (DEBUG_BROADCAST) {
16114                int seq = r.intent.getIntExtra("seq", -1);
16115                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16116            }
16117            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16118            if (!replaced) {
16119                queue.enqueueOrderedBroadcastLocked(r);
16120                queue.scheduleBroadcastsLocked();
16121            }
16122        }
16123
16124        return ActivityManager.BROADCAST_SUCCESS;
16125    }
16126
16127    final Intent verifyBroadcastLocked(Intent intent) {
16128        // Refuse possible leaked file descriptors
16129        if (intent != null && intent.hasFileDescriptors() == true) {
16130            throw new IllegalArgumentException("File descriptors passed in Intent");
16131        }
16132
16133        int flags = intent.getFlags();
16134
16135        if (!mProcessesReady) {
16136            // if the caller really truly claims to know what they're doing, go
16137            // ahead and allow the broadcast without launching any receivers
16138            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16139                intent = new Intent(intent);
16140                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16141            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16142                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16143                        + " before boot completion");
16144                throw new IllegalStateException("Cannot broadcast before boot completed");
16145            }
16146        }
16147
16148        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16149            throw new IllegalArgumentException(
16150                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16151        }
16152
16153        return intent;
16154    }
16155
16156    public final int broadcastIntent(IApplicationThread caller,
16157            Intent intent, String resolvedType, IIntentReceiver resultTo,
16158            int resultCode, String resultData, Bundle map,
16159            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16160        enforceNotIsolatedCaller("broadcastIntent");
16161        synchronized(this) {
16162            intent = verifyBroadcastLocked(intent);
16163
16164            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16165            final int callingPid = Binder.getCallingPid();
16166            final int callingUid = Binder.getCallingUid();
16167            final long origId = Binder.clearCallingIdentity();
16168            int res = broadcastIntentLocked(callerApp,
16169                    callerApp != null ? callerApp.info.packageName : null,
16170                    intent, resolvedType, resultTo,
16171                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16172                    callingPid, callingUid, userId);
16173            Binder.restoreCallingIdentity(origId);
16174            return res;
16175        }
16176    }
16177
16178    int broadcastIntentInPackage(String packageName, int uid,
16179            Intent intent, String resolvedType, IIntentReceiver resultTo,
16180            int resultCode, String resultData, Bundle map,
16181            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16182        synchronized(this) {
16183            intent = verifyBroadcastLocked(intent);
16184
16185            final long origId = Binder.clearCallingIdentity();
16186            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16187                    resultTo, resultCode, resultData, map, requiredPermission,
16188                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16189            Binder.restoreCallingIdentity(origId);
16190            return res;
16191        }
16192    }
16193
16194    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16195        // Refuse possible leaked file descriptors
16196        if (intent != null && intent.hasFileDescriptors() == true) {
16197            throw new IllegalArgumentException("File descriptors passed in Intent");
16198        }
16199
16200        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16201                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16202
16203        synchronized(this) {
16204            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16205                    != PackageManager.PERMISSION_GRANTED) {
16206                String msg = "Permission Denial: unbroadcastIntent() from pid="
16207                        + Binder.getCallingPid()
16208                        + ", uid=" + Binder.getCallingUid()
16209                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16210                Slog.w(TAG, msg);
16211                throw new SecurityException(msg);
16212            }
16213            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16214            if (stickies != null) {
16215                ArrayList<Intent> list = stickies.get(intent.getAction());
16216                if (list != null) {
16217                    int N = list.size();
16218                    int i;
16219                    for (i=0; i<N; i++) {
16220                        if (intent.filterEquals(list.get(i))) {
16221                            list.remove(i);
16222                            break;
16223                        }
16224                    }
16225                    if (list.size() <= 0) {
16226                        stickies.remove(intent.getAction());
16227                    }
16228                }
16229                if (stickies.size() <= 0) {
16230                    mStickyBroadcasts.remove(userId);
16231                }
16232            }
16233        }
16234    }
16235
16236    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16237            String resultData, Bundle resultExtras, boolean resultAbort) {
16238        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16239        if (r == null) {
16240            Slog.w(TAG, "finishReceiver called but not found on queue");
16241            return false;
16242        }
16243
16244        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16245    }
16246
16247    void backgroundServicesFinishedLocked(int userId) {
16248        for (BroadcastQueue queue : mBroadcastQueues) {
16249            queue.backgroundServicesFinishedLocked(userId);
16250        }
16251    }
16252
16253    public void finishReceiver(IBinder who, int resultCode, String resultData,
16254            Bundle resultExtras, boolean resultAbort) {
16255        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16256
16257        // Refuse possible leaked file descriptors
16258        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16259            throw new IllegalArgumentException("File descriptors passed in Bundle");
16260        }
16261
16262        final long origId = Binder.clearCallingIdentity();
16263        try {
16264            boolean doNext = false;
16265            BroadcastRecord r;
16266
16267            synchronized(this) {
16268                r = broadcastRecordForReceiverLocked(who);
16269                if (r != null) {
16270                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16271                        resultData, resultExtras, resultAbort, true);
16272                }
16273            }
16274
16275            if (doNext) {
16276                r.queue.processNextBroadcast(false);
16277            }
16278            trimApplications();
16279        } finally {
16280            Binder.restoreCallingIdentity(origId);
16281        }
16282    }
16283
16284    // =========================================================
16285    // INSTRUMENTATION
16286    // =========================================================
16287
16288    public boolean startInstrumentation(ComponentName className,
16289            String profileFile, int flags, Bundle arguments,
16290            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16291            int userId, String abiOverride) {
16292        enforceNotIsolatedCaller("startInstrumentation");
16293        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16294                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16295        // Refuse possible leaked file descriptors
16296        if (arguments != null && arguments.hasFileDescriptors()) {
16297            throw new IllegalArgumentException("File descriptors passed in Bundle");
16298        }
16299
16300        synchronized(this) {
16301            InstrumentationInfo ii = null;
16302            ApplicationInfo ai = null;
16303            try {
16304                ii = mContext.getPackageManager().getInstrumentationInfo(
16305                    className, STOCK_PM_FLAGS);
16306                ai = AppGlobals.getPackageManager().getApplicationInfo(
16307                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16308            } catch (PackageManager.NameNotFoundException e) {
16309            } catch (RemoteException e) {
16310            }
16311            if (ii == null) {
16312                reportStartInstrumentationFailure(watcher, className,
16313                        "Unable to find instrumentation info for: " + className);
16314                return false;
16315            }
16316            if (ai == null) {
16317                reportStartInstrumentationFailure(watcher, className,
16318                        "Unable to find instrumentation target package: " + ii.targetPackage);
16319                return false;
16320            }
16321
16322            int match = mContext.getPackageManager().checkSignatures(
16323                    ii.targetPackage, ii.packageName);
16324            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16325                String msg = "Permission Denial: starting instrumentation "
16326                        + className + " from pid="
16327                        + Binder.getCallingPid()
16328                        + ", uid=" + Binder.getCallingPid()
16329                        + " not allowed because package " + ii.packageName
16330                        + " does not have a signature matching the target "
16331                        + ii.targetPackage;
16332                reportStartInstrumentationFailure(watcher, className, msg);
16333                throw new SecurityException(msg);
16334            }
16335
16336            final long origId = Binder.clearCallingIdentity();
16337            // Instrumentation can kill and relaunch even persistent processes
16338            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16339                    "start instr");
16340            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16341            app.instrumentationClass = className;
16342            app.instrumentationInfo = ai;
16343            app.instrumentationProfileFile = profileFile;
16344            app.instrumentationArguments = arguments;
16345            app.instrumentationWatcher = watcher;
16346            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16347            app.instrumentationResultClass = className;
16348            Binder.restoreCallingIdentity(origId);
16349        }
16350
16351        return true;
16352    }
16353
16354    /**
16355     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16356     * error to the logs, but if somebody is watching, send the report there too.  This enables
16357     * the "am" command to report errors with more information.
16358     *
16359     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16360     * @param cn The component name of the instrumentation.
16361     * @param report The error report.
16362     */
16363    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16364            ComponentName cn, String report) {
16365        Slog.w(TAG, report);
16366        try {
16367            if (watcher != null) {
16368                Bundle results = new Bundle();
16369                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16370                results.putString("Error", report);
16371                watcher.instrumentationStatus(cn, -1, results);
16372            }
16373        } catch (RemoteException e) {
16374            Slog.w(TAG, e);
16375        }
16376    }
16377
16378    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16379        if (app.instrumentationWatcher != null) {
16380            try {
16381                // NOTE:  IInstrumentationWatcher *must* be oneway here
16382                app.instrumentationWatcher.instrumentationFinished(
16383                    app.instrumentationClass,
16384                    resultCode,
16385                    results);
16386            } catch (RemoteException e) {
16387            }
16388        }
16389        if (app.instrumentationUiAutomationConnection != null) {
16390            try {
16391                app.instrumentationUiAutomationConnection.shutdown();
16392            } catch (RemoteException re) {
16393                /* ignore */
16394            }
16395            // Only a UiAutomation can set this flag and now that
16396            // it is finished we make sure it is reset to its default.
16397            mUserIsMonkey = false;
16398        }
16399        app.instrumentationWatcher = null;
16400        app.instrumentationUiAutomationConnection = null;
16401        app.instrumentationClass = null;
16402        app.instrumentationInfo = null;
16403        app.instrumentationProfileFile = null;
16404        app.instrumentationArguments = null;
16405
16406        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16407                "finished inst");
16408    }
16409
16410    public void finishInstrumentation(IApplicationThread target,
16411            int resultCode, Bundle results) {
16412        int userId = UserHandle.getCallingUserId();
16413        // Refuse possible leaked file descriptors
16414        if (results != null && results.hasFileDescriptors()) {
16415            throw new IllegalArgumentException("File descriptors passed in Intent");
16416        }
16417
16418        synchronized(this) {
16419            ProcessRecord app = getRecordForAppLocked(target);
16420            if (app == null) {
16421                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16422                return;
16423            }
16424            final long origId = Binder.clearCallingIdentity();
16425            finishInstrumentationLocked(app, resultCode, results);
16426            Binder.restoreCallingIdentity(origId);
16427        }
16428    }
16429
16430    // =========================================================
16431    // CONFIGURATION
16432    // =========================================================
16433
16434    public ConfigurationInfo getDeviceConfigurationInfo() {
16435        ConfigurationInfo config = new ConfigurationInfo();
16436        synchronized (this) {
16437            config.reqTouchScreen = mConfiguration.touchscreen;
16438            config.reqKeyboardType = mConfiguration.keyboard;
16439            config.reqNavigation = mConfiguration.navigation;
16440            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16441                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16442                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16443            }
16444            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16445                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16446                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16447            }
16448            config.reqGlEsVersion = GL_ES_VERSION;
16449        }
16450        return config;
16451    }
16452
16453    ActivityStack getFocusedStack() {
16454        return mStackSupervisor.getFocusedStack();
16455    }
16456
16457    public Configuration getConfiguration() {
16458        Configuration ci;
16459        synchronized(this) {
16460            ci = new Configuration(mConfiguration);
16461        }
16462        return ci;
16463    }
16464
16465    public void updatePersistentConfiguration(Configuration values) {
16466        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16467                "updateConfiguration()");
16468        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16469                "updateConfiguration()");
16470        if (values == null) {
16471            throw new NullPointerException("Configuration must not be null");
16472        }
16473
16474        synchronized(this) {
16475            final long origId = Binder.clearCallingIdentity();
16476            updateConfigurationLocked(values, null, true, false);
16477            Binder.restoreCallingIdentity(origId);
16478        }
16479    }
16480
16481    public void updateConfiguration(Configuration values) {
16482        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16483                "updateConfiguration()");
16484
16485        synchronized(this) {
16486            if (values == null && mWindowManager != null) {
16487                // sentinel: fetch the current configuration from the window manager
16488                values = mWindowManager.computeNewConfiguration();
16489            }
16490
16491            if (mWindowManager != null) {
16492                mProcessList.applyDisplaySize(mWindowManager);
16493            }
16494
16495            final long origId = Binder.clearCallingIdentity();
16496            if (values != null) {
16497                Settings.System.clearConfiguration(values);
16498            }
16499            updateConfigurationLocked(values, null, false, false);
16500            Binder.restoreCallingIdentity(origId);
16501        }
16502    }
16503
16504    /**
16505     * Do either or both things: (1) change the current configuration, and (2)
16506     * make sure the given activity is running with the (now) current
16507     * configuration.  Returns true if the activity has been left running, or
16508     * false if <var>starting</var> is being destroyed to match the new
16509     * configuration.
16510     * @param persistent TODO
16511     */
16512    boolean updateConfigurationLocked(Configuration values,
16513            ActivityRecord starting, boolean persistent, boolean initLocale) {
16514        int changes = 0;
16515
16516        if (values != null) {
16517            Configuration newConfig = new Configuration(mConfiguration);
16518            changes = newConfig.updateFrom(values);
16519            if (changes != 0) {
16520                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16521                    Slog.i(TAG, "Updating configuration to: " + values);
16522                }
16523
16524                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16525
16526                if (values.locale != null && !initLocale) {
16527                    saveLocaleLocked(values.locale,
16528                                     !values.locale.equals(mConfiguration.locale),
16529                                     values.userSetLocale);
16530                }
16531
16532                mConfigurationSeq++;
16533                if (mConfigurationSeq <= 0) {
16534                    mConfigurationSeq = 1;
16535                }
16536                newConfig.seq = mConfigurationSeq;
16537                mConfiguration = newConfig;
16538                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16539                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16540                //mUsageStatsService.noteStartConfig(newConfig);
16541
16542                final Configuration configCopy = new Configuration(mConfiguration);
16543
16544                // TODO: If our config changes, should we auto dismiss any currently
16545                // showing dialogs?
16546                mShowDialogs = shouldShowDialogs(newConfig);
16547
16548                AttributeCache ac = AttributeCache.instance();
16549                if (ac != null) {
16550                    ac.updateConfiguration(configCopy);
16551                }
16552
16553                // Make sure all resources in our process are updated
16554                // right now, so that anyone who is going to retrieve
16555                // resource values after we return will be sure to get
16556                // the new ones.  This is especially important during
16557                // boot, where the first config change needs to guarantee
16558                // all resources have that config before following boot
16559                // code is executed.
16560                mSystemThread.applyConfigurationToResources(configCopy);
16561
16562                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16563                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16564                    msg.obj = new Configuration(configCopy);
16565                    mHandler.sendMessage(msg);
16566                }
16567
16568                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16569                    ProcessRecord app = mLruProcesses.get(i);
16570                    try {
16571                        if (app.thread != null) {
16572                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16573                                    + app.processName + " new config " + mConfiguration);
16574                            app.thread.scheduleConfigurationChanged(configCopy);
16575                        }
16576                    } catch (Exception e) {
16577                    }
16578                }
16579                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16580                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16581                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16582                        | Intent.FLAG_RECEIVER_FOREGROUND);
16583                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16584                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16585                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16586                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16587                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16588                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16589                    broadcastIntentLocked(null, null, intent,
16590                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16591                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16592                }
16593            }
16594        }
16595
16596        boolean kept = true;
16597        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16598        // mainStack is null during startup.
16599        if (mainStack != null) {
16600            if (changes != 0 && starting == null) {
16601                // If the configuration changed, and the caller is not already
16602                // in the process of starting an activity, then find the top
16603                // activity to check if its configuration needs to change.
16604                starting = mainStack.topRunningActivityLocked(null);
16605            }
16606
16607            if (starting != null) {
16608                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16609                // And we need to make sure at this point that all other activities
16610                // are made visible with the correct configuration.
16611                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16612            }
16613        }
16614
16615        if (values != null && mWindowManager != null) {
16616            mWindowManager.setNewConfiguration(mConfiguration);
16617        }
16618
16619        return kept;
16620    }
16621
16622    /**
16623     * Decide based on the configuration whether we should shouw the ANR,
16624     * crash, etc dialogs.  The idea is that if there is no affordnace to
16625     * press the on-screen buttons, we shouldn't show the dialog.
16626     *
16627     * A thought: SystemUI might also want to get told about this, the Power
16628     * dialog / global actions also might want different behaviors.
16629     */
16630    private static final boolean shouldShowDialogs(Configuration config) {
16631        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16632                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16633    }
16634
16635    /**
16636     * Save the locale.  You must be inside a synchronized (this) block.
16637     */
16638    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16639        if(isDiff) {
16640            SystemProperties.set("user.language", l.getLanguage());
16641            SystemProperties.set("user.region", l.getCountry());
16642        }
16643
16644        if(isPersist) {
16645            SystemProperties.set("persist.sys.language", l.getLanguage());
16646            SystemProperties.set("persist.sys.country", l.getCountry());
16647            SystemProperties.set("persist.sys.localevar", l.getVariant());
16648
16649            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16650        }
16651    }
16652
16653    @Override
16654    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16655        synchronized (this) {
16656            ActivityRecord srec = ActivityRecord.forToken(token);
16657            if (srec.task != null && srec.task.stack != null) {
16658                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16659            }
16660        }
16661        return false;
16662    }
16663
16664    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16665            Intent resultData) {
16666
16667        synchronized (this) {
16668            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16669            if (stack != null) {
16670                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16671            }
16672            return false;
16673        }
16674    }
16675
16676    public int getLaunchedFromUid(IBinder activityToken) {
16677        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16678        if (srec == null) {
16679            return -1;
16680        }
16681        return srec.launchedFromUid;
16682    }
16683
16684    public String getLaunchedFromPackage(IBinder activityToken) {
16685        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16686        if (srec == null) {
16687            return null;
16688        }
16689        return srec.launchedFromPackage;
16690    }
16691
16692    // =========================================================
16693    // LIFETIME MANAGEMENT
16694    // =========================================================
16695
16696    // Returns which broadcast queue the app is the current [or imminent] receiver
16697    // on, or 'null' if the app is not an active broadcast recipient.
16698    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16699        BroadcastRecord r = app.curReceiver;
16700        if (r != null) {
16701            return r.queue;
16702        }
16703
16704        // It's not the current receiver, but it might be starting up to become one
16705        synchronized (this) {
16706            for (BroadcastQueue queue : mBroadcastQueues) {
16707                r = queue.mPendingBroadcast;
16708                if (r != null && r.curApp == app) {
16709                    // found it; report which queue it's in
16710                    return queue;
16711                }
16712            }
16713        }
16714
16715        return null;
16716    }
16717
16718    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16719            boolean doingAll, long now) {
16720        if (mAdjSeq == app.adjSeq) {
16721            // This adjustment has already been computed.
16722            return app.curRawAdj;
16723        }
16724
16725        if (app.thread == null) {
16726            app.adjSeq = mAdjSeq;
16727            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16728            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16729            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16730        }
16731
16732        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16733        app.adjSource = null;
16734        app.adjTarget = null;
16735        app.empty = false;
16736        app.cached = false;
16737
16738        final int activitiesSize = app.activities.size();
16739
16740        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16741            // The max adjustment doesn't allow this app to be anything
16742            // below foreground, so it is not worth doing work for it.
16743            app.adjType = "fixed";
16744            app.adjSeq = mAdjSeq;
16745            app.curRawAdj = app.maxAdj;
16746            app.foregroundActivities = false;
16747            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16748            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16749            // System processes can do UI, and when they do we want to have
16750            // them trim their memory after the user leaves the UI.  To
16751            // facilitate this, here we need to determine whether or not it
16752            // is currently showing UI.
16753            app.systemNoUi = true;
16754            if (app == TOP_APP) {
16755                app.systemNoUi = false;
16756            } else if (activitiesSize > 0) {
16757                for (int j = 0; j < activitiesSize; j++) {
16758                    final ActivityRecord r = app.activities.get(j);
16759                    if (r.visible) {
16760                        app.systemNoUi = false;
16761                    }
16762                }
16763            }
16764            if (!app.systemNoUi) {
16765                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16766            }
16767            return (app.curAdj=app.maxAdj);
16768        }
16769
16770        app.systemNoUi = false;
16771
16772        // Determine the importance of the process, starting with most
16773        // important to least, and assign an appropriate OOM adjustment.
16774        int adj;
16775        int schedGroup;
16776        int procState;
16777        boolean foregroundActivities = false;
16778        BroadcastQueue queue;
16779        if (app == TOP_APP) {
16780            // The last app on the list is the foreground app.
16781            adj = ProcessList.FOREGROUND_APP_ADJ;
16782            schedGroup = Process.THREAD_GROUP_DEFAULT;
16783            app.adjType = "top-activity";
16784            foregroundActivities = true;
16785            procState = ActivityManager.PROCESS_STATE_TOP;
16786        } else if (app.instrumentationClass != null) {
16787            // Don't want to kill running instrumentation.
16788            adj = ProcessList.FOREGROUND_APP_ADJ;
16789            schedGroup = Process.THREAD_GROUP_DEFAULT;
16790            app.adjType = "instrumentation";
16791            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16792        } else if ((queue = isReceivingBroadcast(app)) != null) {
16793            // An app that is currently receiving a broadcast also
16794            // counts as being in the foreground for OOM killer purposes.
16795            // It's placed in a sched group based on the nature of the
16796            // broadcast as reflected by which queue it's active in.
16797            adj = ProcessList.FOREGROUND_APP_ADJ;
16798            schedGroup = (queue == mFgBroadcastQueue)
16799                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16800            app.adjType = "broadcast";
16801            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16802        } else if (app.executingServices.size() > 0) {
16803            // An app that is currently executing a service callback also
16804            // counts as being in the foreground.
16805            adj = ProcessList.FOREGROUND_APP_ADJ;
16806            schedGroup = app.execServicesFg ?
16807                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16808            app.adjType = "exec-service";
16809            procState = ActivityManager.PROCESS_STATE_SERVICE;
16810            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16811        } else {
16812            // As far as we know the process is empty.  We may change our mind later.
16813            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16814            // At this point we don't actually know the adjustment.  Use the cached adj
16815            // value that the caller wants us to.
16816            adj = cachedAdj;
16817            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16818            app.cached = true;
16819            app.empty = true;
16820            app.adjType = "cch-empty";
16821        }
16822
16823        // Examine all activities if not already foreground.
16824        if (!foregroundActivities && activitiesSize > 0) {
16825            for (int j = 0; j < activitiesSize; j++) {
16826                final ActivityRecord r = app.activities.get(j);
16827                if (r.app != app) {
16828                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16829                            + app + "?!?");
16830                    continue;
16831                }
16832                if (r.visible) {
16833                    // App has a visible activity; only upgrade adjustment.
16834                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16835                        adj = ProcessList.VISIBLE_APP_ADJ;
16836                        app.adjType = "visible";
16837                    }
16838                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16839                        procState = ActivityManager.PROCESS_STATE_TOP;
16840                    }
16841                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16842                    app.cached = false;
16843                    app.empty = false;
16844                    foregroundActivities = true;
16845                    break;
16846                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16847                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16848                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16849                        app.adjType = "pausing";
16850                    }
16851                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16852                        procState = ActivityManager.PROCESS_STATE_TOP;
16853                    }
16854                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16855                    app.cached = false;
16856                    app.empty = false;
16857                    foregroundActivities = true;
16858                } else if (r.state == ActivityState.STOPPING) {
16859                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16860                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16861                        app.adjType = "stopping";
16862                    }
16863                    // For the process state, we will at this point consider the
16864                    // process to be cached.  It will be cached either as an activity
16865                    // or empty depending on whether the activity is finishing.  We do
16866                    // this so that we can treat the process as cached for purposes of
16867                    // memory trimming (determing current memory level, trim command to
16868                    // send to process) since there can be an arbitrary number of stopping
16869                    // processes and they should soon all go into the cached state.
16870                    if (!r.finishing) {
16871                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16872                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16873                        }
16874                    }
16875                    app.cached = false;
16876                    app.empty = false;
16877                    foregroundActivities = true;
16878                } else {
16879                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16880                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16881                        app.adjType = "cch-act";
16882                    }
16883                }
16884            }
16885        }
16886
16887        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16888            if (app.foregroundServices) {
16889                // The user is aware of this app, so make it visible.
16890                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16891                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16892                app.cached = false;
16893                app.adjType = "fg-service";
16894                schedGroup = Process.THREAD_GROUP_DEFAULT;
16895            } else if (app.forcingToForeground != null) {
16896                // The user is aware of this app, so make it visible.
16897                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16898                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16899                app.cached = false;
16900                app.adjType = "force-fg";
16901                app.adjSource = app.forcingToForeground;
16902                schedGroup = Process.THREAD_GROUP_DEFAULT;
16903            }
16904        }
16905
16906        if (app == mHeavyWeightProcess) {
16907            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16908                // We don't want to kill the current heavy-weight process.
16909                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16910                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16911                app.cached = false;
16912                app.adjType = "heavy";
16913            }
16914            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16915                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16916            }
16917        }
16918
16919        if (app == mHomeProcess) {
16920            if (adj > ProcessList.HOME_APP_ADJ) {
16921                // This process is hosting what we currently consider to be the
16922                // home app, so we don't want to let it go into the background.
16923                adj = ProcessList.HOME_APP_ADJ;
16924                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16925                app.cached = false;
16926                app.adjType = "home";
16927            }
16928            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16929                procState = ActivityManager.PROCESS_STATE_HOME;
16930            }
16931        }
16932
16933        if (app == mPreviousProcess && app.activities.size() > 0) {
16934            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16935                // This was the previous process that showed UI to the user.
16936                // We want to try to keep it around more aggressively, to give
16937                // a good experience around switching between two apps.
16938                adj = ProcessList.PREVIOUS_APP_ADJ;
16939                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16940                app.cached = false;
16941                app.adjType = "previous";
16942            }
16943            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16944                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16945            }
16946        }
16947
16948        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16949                + " reason=" + app.adjType);
16950
16951        // By default, we use the computed adjustment.  It may be changed if
16952        // there are applications dependent on our services or providers, but
16953        // this gives us a baseline and makes sure we don't get into an
16954        // infinite recursion.
16955        app.adjSeq = mAdjSeq;
16956        app.curRawAdj = adj;
16957        app.hasStartedServices = false;
16958
16959        if (mBackupTarget != null && app == mBackupTarget.app) {
16960            // If possible we want to avoid killing apps while they're being backed up
16961            if (adj > ProcessList.BACKUP_APP_ADJ) {
16962                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16963                adj = ProcessList.BACKUP_APP_ADJ;
16964                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16965                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16966                }
16967                app.adjType = "backup";
16968                app.cached = false;
16969            }
16970            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16971                procState = ActivityManager.PROCESS_STATE_BACKUP;
16972            }
16973        }
16974
16975        boolean mayBeTop = false;
16976
16977        for (int is = app.services.size()-1;
16978                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16979                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16980                        || procState > ActivityManager.PROCESS_STATE_TOP);
16981                is--) {
16982            ServiceRecord s = app.services.valueAt(is);
16983            if (s.startRequested) {
16984                app.hasStartedServices = true;
16985                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16986                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16987                }
16988                if (app.hasShownUi && app != mHomeProcess) {
16989                    // If this process has shown some UI, let it immediately
16990                    // go to the LRU list because it may be pretty heavy with
16991                    // UI stuff.  We'll tag it with a label just to help
16992                    // debug and understand what is going on.
16993                    if (adj > ProcessList.SERVICE_ADJ) {
16994                        app.adjType = "cch-started-ui-services";
16995                    }
16996                } else {
16997                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16998                        // This service has seen some activity within
16999                        // recent memory, so we will keep its process ahead
17000                        // of the background processes.
17001                        if (adj > ProcessList.SERVICE_ADJ) {
17002                            adj = ProcessList.SERVICE_ADJ;
17003                            app.adjType = "started-services";
17004                            app.cached = false;
17005                        }
17006                    }
17007                    // If we have let the service slide into the background
17008                    // state, still have some text describing what it is doing
17009                    // even though the service no longer has an impact.
17010                    if (adj > ProcessList.SERVICE_ADJ) {
17011                        app.adjType = "cch-started-services";
17012                    }
17013                }
17014            }
17015            for (int conni = s.connections.size()-1;
17016                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17017                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17018                            || procState > ActivityManager.PROCESS_STATE_TOP);
17019                    conni--) {
17020                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17021                for (int i = 0;
17022                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17023                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17024                                || procState > ActivityManager.PROCESS_STATE_TOP);
17025                        i++) {
17026                    // XXX should compute this based on the max of
17027                    // all connected clients.
17028                    ConnectionRecord cr = clist.get(i);
17029                    if (cr.binding.client == app) {
17030                        // Binding to ourself is not interesting.
17031                        continue;
17032                    }
17033                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17034                        ProcessRecord client = cr.binding.client;
17035                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17036                                TOP_APP, doingAll, now);
17037                        int clientProcState = client.curProcState;
17038                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17039                            // If the other app is cached for any reason, for purposes here
17040                            // we are going to consider it empty.  The specific cached state
17041                            // doesn't propagate except under certain conditions.
17042                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17043                        }
17044                        String adjType = null;
17045                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17046                            // Not doing bind OOM management, so treat
17047                            // this guy more like a started service.
17048                            if (app.hasShownUi && app != mHomeProcess) {
17049                                // If this process has shown some UI, let it immediately
17050                                // go to the LRU list because it may be pretty heavy with
17051                                // UI stuff.  We'll tag it with a label just to help
17052                                // debug and understand what is going on.
17053                                if (adj > clientAdj) {
17054                                    adjType = "cch-bound-ui-services";
17055                                }
17056                                app.cached = false;
17057                                clientAdj = adj;
17058                                clientProcState = procState;
17059                            } else {
17060                                if (now >= (s.lastActivity
17061                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17062                                    // This service has not seen activity within
17063                                    // recent memory, so allow it to drop to the
17064                                    // LRU list if there is no other reason to keep
17065                                    // it around.  We'll also tag it with a label just
17066                                    // to help debug and undertand what is going on.
17067                                    if (adj > clientAdj) {
17068                                        adjType = "cch-bound-services";
17069                                    }
17070                                    clientAdj = adj;
17071                                }
17072                            }
17073                        }
17074                        if (adj > clientAdj) {
17075                            // If this process has recently shown UI, and
17076                            // the process that is binding to it is less
17077                            // important than being visible, then we don't
17078                            // care about the binding as much as we care
17079                            // about letting this process get into the LRU
17080                            // list to be killed and restarted if needed for
17081                            // memory.
17082                            if (app.hasShownUi && app != mHomeProcess
17083                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17084                                adjType = "cch-bound-ui-services";
17085                            } else {
17086                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17087                                        |Context.BIND_IMPORTANT)) != 0) {
17088                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17089                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17090                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17091                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17092                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17093                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17094                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17095                                    adj = clientAdj;
17096                                } else {
17097                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17098                                        adj = ProcessList.VISIBLE_APP_ADJ;
17099                                    }
17100                                }
17101                                if (!client.cached) {
17102                                    app.cached = false;
17103                                }
17104                                adjType = "service";
17105                            }
17106                        }
17107                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17108                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17109                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17110                            }
17111                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17112                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17113                                    // Special handling of clients who are in the top state.
17114                                    // We *may* want to consider this process to be in the
17115                                    // top state as well, but only if there is not another
17116                                    // reason for it to be running.  Being on the top is a
17117                                    // special state, meaning you are specifically running
17118                                    // for the current top app.  If the process is already
17119                                    // running in the background for some other reason, it
17120                                    // is more important to continue considering it to be
17121                                    // in the background state.
17122                                    mayBeTop = true;
17123                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17124                                } else {
17125                                    // Special handling for above-top states (persistent
17126                                    // processes).  These should not bring the current process
17127                                    // into the top state, since they are not on top.  Instead
17128                                    // give them the best state after that.
17129                                    clientProcState =
17130                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17131                                }
17132                            }
17133                        } else {
17134                            if (clientProcState <
17135                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17136                                clientProcState =
17137                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17138                            }
17139                        }
17140                        if (procState > clientProcState) {
17141                            procState = clientProcState;
17142                        }
17143                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17144                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17145                            app.pendingUiClean = true;
17146                        }
17147                        if (adjType != null) {
17148                            app.adjType = adjType;
17149                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17150                                    .REASON_SERVICE_IN_USE;
17151                            app.adjSource = cr.binding.client;
17152                            app.adjSourceProcState = clientProcState;
17153                            app.adjTarget = s.name;
17154                        }
17155                    }
17156                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17157                        app.treatLikeActivity = true;
17158                    }
17159                    final ActivityRecord a = cr.activity;
17160                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17161                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17162                                (a.visible || a.state == ActivityState.RESUMED
17163                                 || a.state == ActivityState.PAUSING)) {
17164                            adj = ProcessList.FOREGROUND_APP_ADJ;
17165                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17166                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17167                            }
17168                            app.cached = false;
17169                            app.adjType = "service";
17170                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17171                                    .REASON_SERVICE_IN_USE;
17172                            app.adjSource = a;
17173                            app.adjSourceProcState = procState;
17174                            app.adjTarget = s.name;
17175                        }
17176                    }
17177                }
17178            }
17179        }
17180
17181        for (int provi = app.pubProviders.size()-1;
17182                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17183                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17184                        || procState > ActivityManager.PROCESS_STATE_TOP);
17185                provi--) {
17186            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17187            for (int i = cpr.connections.size()-1;
17188                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17189                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17190                            || procState > ActivityManager.PROCESS_STATE_TOP);
17191                    i--) {
17192                ContentProviderConnection conn = cpr.connections.get(i);
17193                ProcessRecord client = conn.client;
17194                if (client == app) {
17195                    // Being our own client is not interesting.
17196                    continue;
17197                }
17198                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17199                int clientProcState = client.curProcState;
17200                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17201                    // If the other app is cached for any reason, for purposes here
17202                    // we are going to consider it empty.
17203                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17204                }
17205                if (adj > clientAdj) {
17206                    if (app.hasShownUi && app != mHomeProcess
17207                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17208                        app.adjType = "cch-ui-provider";
17209                    } else {
17210                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17211                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17212                        app.adjType = "provider";
17213                    }
17214                    app.cached &= client.cached;
17215                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17216                            .REASON_PROVIDER_IN_USE;
17217                    app.adjSource = client;
17218                    app.adjSourceProcState = clientProcState;
17219                    app.adjTarget = cpr.name;
17220                }
17221                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17222                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17223                        // Special handling of clients who are in the top state.
17224                        // We *may* want to consider this process to be in the
17225                        // top state as well, but only if there is not another
17226                        // reason for it to be running.  Being on the top is a
17227                        // special state, meaning you are specifically running
17228                        // for the current top app.  If the process is already
17229                        // running in the background for some other reason, it
17230                        // is more important to continue considering it to be
17231                        // in the background state.
17232                        mayBeTop = true;
17233                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17234                    } else {
17235                        // Special handling for above-top states (persistent
17236                        // processes).  These should not bring the current process
17237                        // into the top state, since they are not on top.  Instead
17238                        // give them the best state after that.
17239                        clientProcState =
17240                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17241                    }
17242                }
17243                if (procState > clientProcState) {
17244                    procState = clientProcState;
17245                }
17246                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17247                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17248                }
17249            }
17250            // If the provider has external (non-framework) process
17251            // dependencies, ensure that its adjustment is at least
17252            // FOREGROUND_APP_ADJ.
17253            if (cpr.hasExternalProcessHandles()) {
17254                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17255                    adj = ProcessList.FOREGROUND_APP_ADJ;
17256                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17257                    app.cached = false;
17258                    app.adjType = "provider";
17259                    app.adjTarget = cpr.name;
17260                }
17261                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17262                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17263                }
17264            }
17265        }
17266
17267        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17268            // A client of one of our services or providers is in the top state.  We
17269            // *may* want to be in the top state, but not if we are already running in
17270            // the background for some other reason.  For the decision here, we are going
17271            // to pick out a few specific states that we want to remain in when a client
17272            // is top (states that tend to be longer-term) and otherwise allow it to go
17273            // to the top state.
17274            switch (procState) {
17275                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17276                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17277                case ActivityManager.PROCESS_STATE_SERVICE:
17278                    // These all are longer-term states, so pull them up to the top
17279                    // of the background states, but not all the way to the top state.
17280                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17281                    break;
17282                default:
17283                    // Otherwise, top is a better choice, so take it.
17284                    procState = ActivityManager.PROCESS_STATE_TOP;
17285                    break;
17286            }
17287        }
17288
17289        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17290            if (app.hasClientActivities) {
17291                // This is a cached process, but with client activities.  Mark it so.
17292                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17293                app.adjType = "cch-client-act";
17294            } else if (app.treatLikeActivity) {
17295                // This is a cached process, but somebody wants us to treat it like it has
17296                // an activity, okay!
17297                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17298                app.adjType = "cch-as-act";
17299            }
17300        }
17301
17302        if (adj == ProcessList.SERVICE_ADJ) {
17303            if (doingAll) {
17304                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17305                mNewNumServiceProcs++;
17306                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17307                if (!app.serviceb) {
17308                    // This service isn't far enough down on the LRU list to
17309                    // normally be a B service, but if we are low on RAM and it
17310                    // is large we want to force it down since we would prefer to
17311                    // keep launcher over it.
17312                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17313                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17314                        app.serviceHighRam = true;
17315                        app.serviceb = true;
17316                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17317                    } else {
17318                        mNewNumAServiceProcs++;
17319                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17320                    }
17321                } else {
17322                    app.serviceHighRam = false;
17323                }
17324            }
17325            if (app.serviceb) {
17326                adj = ProcessList.SERVICE_B_ADJ;
17327            }
17328        }
17329
17330        app.curRawAdj = adj;
17331
17332        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17333        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17334        if (adj > app.maxAdj) {
17335            adj = app.maxAdj;
17336            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17337                schedGroup = Process.THREAD_GROUP_DEFAULT;
17338            }
17339        }
17340
17341        // Do final modification to adj.  Everything we do between here and applying
17342        // the final setAdj must be done in this function, because we will also use
17343        // it when computing the final cached adj later.  Note that we don't need to
17344        // worry about this for max adj above, since max adj will always be used to
17345        // keep it out of the cached vaues.
17346        app.curAdj = app.modifyRawOomAdj(adj);
17347        app.curSchedGroup = schedGroup;
17348        app.curProcState = procState;
17349        app.foregroundActivities = foregroundActivities;
17350
17351        return app.curRawAdj;
17352    }
17353
17354    /**
17355     * Record new PSS sample for a process.
17356     */
17357    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17358        proc.lastPssTime = now;
17359        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17360        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17361                + ": " + pss + " lastPss=" + proc.lastPss
17362                + " state=" + ProcessList.makeProcStateString(procState));
17363        if (proc.initialIdlePss == 0) {
17364            proc.initialIdlePss = pss;
17365        }
17366        proc.lastPss = pss;
17367        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17368            proc.lastCachedPss = pss;
17369        }
17370    }
17371
17372    /**
17373     * Schedule PSS collection of a process.
17374     */
17375    void requestPssLocked(ProcessRecord proc, int procState) {
17376        if (mPendingPssProcesses.contains(proc)) {
17377            return;
17378        }
17379        if (mPendingPssProcesses.size() == 0) {
17380            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17381        }
17382        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17383        proc.pssProcState = procState;
17384        mPendingPssProcesses.add(proc);
17385    }
17386
17387    /**
17388     * Schedule PSS collection of all processes.
17389     */
17390    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17391        if (!always) {
17392            if (now < (mLastFullPssTime +
17393                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17394                return;
17395            }
17396        }
17397        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17398        mLastFullPssTime = now;
17399        mFullPssPending = true;
17400        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17401        mPendingPssProcesses.clear();
17402        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17403            ProcessRecord app = mLruProcesses.get(i);
17404            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17405                app.pssProcState = app.setProcState;
17406                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17407                        mTestPssMode, isSleeping(), now);
17408                mPendingPssProcesses.add(app);
17409            }
17410        }
17411        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17412    }
17413
17414    public void setTestPssMode(boolean enabled) {
17415        synchronized (this) {
17416            mTestPssMode = enabled;
17417            if (enabled) {
17418                // Whenever we enable the mode, we want to take a snapshot all of current
17419                // process mem use.
17420                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17421            }
17422        }
17423    }
17424
17425    /**
17426     * Ask a given process to GC right now.
17427     */
17428    final void performAppGcLocked(ProcessRecord app) {
17429        try {
17430            app.lastRequestedGc = SystemClock.uptimeMillis();
17431            if (app.thread != null) {
17432                if (app.reportLowMemory) {
17433                    app.reportLowMemory = false;
17434                    app.thread.scheduleLowMemory();
17435                } else {
17436                    app.thread.processInBackground();
17437                }
17438            }
17439        } catch (Exception e) {
17440            // whatever.
17441        }
17442    }
17443
17444    /**
17445     * Returns true if things are idle enough to perform GCs.
17446     */
17447    private final boolean canGcNowLocked() {
17448        boolean processingBroadcasts = false;
17449        for (BroadcastQueue q : mBroadcastQueues) {
17450            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17451                processingBroadcasts = true;
17452            }
17453        }
17454        return !processingBroadcasts
17455                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17456    }
17457
17458    /**
17459     * Perform GCs on all processes that are waiting for it, but only
17460     * if things are idle.
17461     */
17462    final void performAppGcsLocked() {
17463        final int N = mProcessesToGc.size();
17464        if (N <= 0) {
17465            return;
17466        }
17467        if (canGcNowLocked()) {
17468            while (mProcessesToGc.size() > 0) {
17469                ProcessRecord proc = mProcessesToGc.remove(0);
17470                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17471                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17472                            <= SystemClock.uptimeMillis()) {
17473                        // To avoid spamming the system, we will GC processes one
17474                        // at a time, waiting a few seconds between each.
17475                        performAppGcLocked(proc);
17476                        scheduleAppGcsLocked();
17477                        return;
17478                    } else {
17479                        // It hasn't been long enough since we last GCed this
17480                        // process...  put it in the list to wait for its time.
17481                        addProcessToGcListLocked(proc);
17482                        break;
17483                    }
17484                }
17485            }
17486
17487            scheduleAppGcsLocked();
17488        }
17489    }
17490
17491    /**
17492     * If all looks good, perform GCs on all processes waiting for them.
17493     */
17494    final void performAppGcsIfAppropriateLocked() {
17495        if (canGcNowLocked()) {
17496            performAppGcsLocked();
17497            return;
17498        }
17499        // Still not idle, wait some more.
17500        scheduleAppGcsLocked();
17501    }
17502
17503    /**
17504     * Schedule the execution of all pending app GCs.
17505     */
17506    final void scheduleAppGcsLocked() {
17507        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17508
17509        if (mProcessesToGc.size() > 0) {
17510            // Schedule a GC for the time to the next process.
17511            ProcessRecord proc = mProcessesToGc.get(0);
17512            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17513
17514            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17515            long now = SystemClock.uptimeMillis();
17516            if (when < (now+GC_TIMEOUT)) {
17517                when = now + GC_TIMEOUT;
17518            }
17519            mHandler.sendMessageAtTime(msg, when);
17520        }
17521    }
17522
17523    /**
17524     * Add a process to the array of processes waiting to be GCed.  Keeps the
17525     * list in sorted order by the last GC time.  The process can't already be
17526     * on the list.
17527     */
17528    final void addProcessToGcListLocked(ProcessRecord proc) {
17529        boolean added = false;
17530        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17531            if (mProcessesToGc.get(i).lastRequestedGc <
17532                    proc.lastRequestedGc) {
17533                added = true;
17534                mProcessesToGc.add(i+1, proc);
17535                break;
17536            }
17537        }
17538        if (!added) {
17539            mProcessesToGc.add(0, proc);
17540        }
17541    }
17542
17543    /**
17544     * Set up to ask a process to GC itself.  This will either do it
17545     * immediately, or put it on the list of processes to gc the next
17546     * time things are idle.
17547     */
17548    final void scheduleAppGcLocked(ProcessRecord app) {
17549        long now = SystemClock.uptimeMillis();
17550        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17551            return;
17552        }
17553        if (!mProcessesToGc.contains(app)) {
17554            addProcessToGcListLocked(app);
17555            scheduleAppGcsLocked();
17556        }
17557    }
17558
17559    final void checkExcessivePowerUsageLocked(boolean doKills) {
17560        updateCpuStatsNow();
17561
17562        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17563        boolean doWakeKills = doKills;
17564        boolean doCpuKills = doKills;
17565        if (mLastPowerCheckRealtime == 0) {
17566            doWakeKills = false;
17567        }
17568        if (mLastPowerCheckUptime == 0) {
17569            doCpuKills = false;
17570        }
17571        if (stats.isScreenOn()) {
17572            doWakeKills = false;
17573        }
17574        final long curRealtime = SystemClock.elapsedRealtime();
17575        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17576        final long curUptime = SystemClock.uptimeMillis();
17577        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17578        mLastPowerCheckRealtime = curRealtime;
17579        mLastPowerCheckUptime = curUptime;
17580        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17581            doWakeKills = false;
17582        }
17583        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17584            doCpuKills = false;
17585        }
17586        int i = mLruProcesses.size();
17587        while (i > 0) {
17588            i--;
17589            ProcessRecord app = mLruProcesses.get(i);
17590            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17591                long wtime;
17592                synchronized (stats) {
17593                    wtime = stats.getProcessWakeTime(app.info.uid,
17594                            app.pid, curRealtime);
17595                }
17596                long wtimeUsed = wtime - app.lastWakeTime;
17597                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17598                if (DEBUG_POWER) {
17599                    StringBuilder sb = new StringBuilder(128);
17600                    sb.append("Wake for ");
17601                    app.toShortString(sb);
17602                    sb.append(": over ");
17603                    TimeUtils.formatDuration(realtimeSince, sb);
17604                    sb.append(" used ");
17605                    TimeUtils.formatDuration(wtimeUsed, sb);
17606                    sb.append(" (");
17607                    sb.append((wtimeUsed*100)/realtimeSince);
17608                    sb.append("%)");
17609                    Slog.i(TAG, sb.toString());
17610                    sb.setLength(0);
17611                    sb.append("CPU for ");
17612                    app.toShortString(sb);
17613                    sb.append(": over ");
17614                    TimeUtils.formatDuration(uptimeSince, sb);
17615                    sb.append(" used ");
17616                    TimeUtils.formatDuration(cputimeUsed, sb);
17617                    sb.append(" (");
17618                    sb.append((cputimeUsed*100)/uptimeSince);
17619                    sb.append("%)");
17620                    Slog.i(TAG, sb.toString());
17621                }
17622                // If a process has held a wake lock for more
17623                // than 50% of the time during this period,
17624                // that sounds bad.  Kill!
17625                if (doWakeKills && realtimeSince > 0
17626                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17627                    synchronized (stats) {
17628                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17629                                realtimeSince, wtimeUsed);
17630                    }
17631                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17632                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17633                } else if (doCpuKills && uptimeSince > 0
17634                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17635                    synchronized (stats) {
17636                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17637                                uptimeSince, cputimeUsed);
17638                    }
17639                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17640                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17641                } else {
17642                    app.lastWakeTime = wtime;
17643                    app.lastCpuTime = app.curCpuTime;
17644                }
17645            }
17646        }
17647    }
17648
17649    private final boolean applyOomAdjLocked(ProcessRecord app,
17650            ProcessRecord TOP_APP, boolean doingAll, long now) {
17651        boolean success = true;
17652
17653        if (app.curRawAdj != app.setRawAdj) {
17654            app.setRawAdj = app.curRawAdj;
17655        }
17656
17657        int changes = 0;
17658
17659        if (app.curAdj != app.setAdj) {
17660            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17661            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17662                TAG, "Set " + app.pid + " " + app.processName +
17663                " adj " + app.curAdj + ": " + app.adjType);
17664            app.setAdj = app.curAdj;
17665        }
17666
17667        if (app.setSchedGroup != app.curSchedGroup) {
17668            app.setSchedGroup = app.curSchedGroup;
17669            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17670                    "Setting process group of " + app.processName
17671                    + " to " + app.curSchedGroup);
17672            if (app.waitingToKill != null &&
17673                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17674                app.kill(app.waitingToKill, true);
17675                success = false;
17676            } else {
17677                if (true) {
17678                    long oldId = Binder.clearCallingIdentity();
17679                    try {
17680                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17681                    } catch (Exception e) {
17682                        Slog.w(TAG, "Failed setting process group of " + app.pid
17683                                + " to " + app.curSchedGroup);
17684                        e.printStackTrace();
17685                    } finally {
17686                        Binder.restoreCallingIdentity(oldId);
17687                    }
17688                } else {
17689                    if (app.thread != null) {
17690                        try {
17691                            app.thread.setSchedulingGroup(app.curSchedGroup);
17692                        } catch (RemoteException e) {
17693                        }
17694                    }
17695                }
17696                Process.setSwappiness(app.pid,
17697                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17698            }
17699        }
17700        if (app.repForegroundActivities != app.foregroundActivities) {
17701            app.repForegroundActivities = app.foregroundActivities;
17702            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17703        }
17704        if (app.repProcState != app.curProcState) {
17705            app.repProcState = app.curProcState;
17706            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17707            if (app.thread != null) {
17708                try {
17709                    if (false) {
17710                        //RuntimeException h = new RuntimeException("here");
17711                        Slog.i(TAG, "Sending new process state " + app.repProcState
17712                                + " to " + app /*, h*/);
17713                    }
17714                    app.thread.setProcessState(app.repProcState);
17715                } catch (RemoteException e) {
17716                }
17717            }
17718        }
17719        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17720                app.setProcState)) {
17721            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17722                // Experimental code to more aggressively collect pss while
17723                // running test...  the problem is that this tends to collect
17724                // the data right when a process is transitioning between process
17725                // states, which well tend to give noisy data.
17726                long start = SystemClock.uptimeMillis();
17727                long pss = Debug.getPss(app.pid, mTmpLong, null);
17728                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17729                mPendingPssProcesses.remove(app);
17730                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17731                        + " to " + app.curProcState + ": "
17732                        + (SystemClock.uptimeMillis()-start) + "ms");
17733            }
17734            app.lastStateTime = now;
17735            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17736                    mTestPssMode, isSleeping(), now);
17737            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17738                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17739                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17740                    + (app.nextPssTime-now) + ": " + app);
17741        } else {
17742            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17743                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17744                    mTestPssMode)))) {
17745                requestPssLocked(app, app.setProcState);
17746                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17747                        mTestPssMode, isSleeping(), now);
17748            } else if (false && DEBUG_PSS) {
17749                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17750            }
17751        }
17752        if (app.setProcState != app.curProcState) {
17753            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17754                    "Proc state change of " + app.processName
17755                    + " to " + app.curProcState);
17756            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17757            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17758            if (setImportant && !curImportant) {
17759                // This app is no longer something we consider important enough to allow to
17760                // use arbitrary amounts of battery power.  Note
17761                // its current wake lock time to later know to kill it if
17762                // it is not behaving well.
17763                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17764                synchronized (stats) {
17765                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17766                            app.pid, SystemClock.elapsedRealtime());
17767                }
17768                app.lastCpuTime = app.curCpuTime;
17769
17770            }
17771            app.setProcState = app.curProcState;
17772            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17773                app.notCachedSinceIdle = false;
17774            }
17775            if (!doingAll) {
17776                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17777            } else {
17778                app.procStateChanged = true;
17779            }
17780        }
17781
17782        if (changes != 0) {
17783            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17784            int i = mPendingProcessChanges.size()-1;
17785            ProcessChangeItem item = null;
17786            while (i >= 0) {
17787                item = mPendingProcessChanges.get(i);
17788                if (item.pid == app.pid) {
17789                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17790                    break;
17791                }
17792                i--;
17793            }
17794            if (i < 0) {
17795                // No existing item in pending changes; need a new one.
17796                final int NA = mAvailProcessChanges.size();
17797                if (NA > 0) {
17798                    item = mAvailProcessChanges.remove(NA-1);
17799                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17800                } else {
17801                    item = new ProcessChangeItem();
17802                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17803                }
17804                item.changes = 0;
17805                item.pid = app.pid;
17806                item.uid = app.info.uid;
17807                if (mPendingProcessChanges.size() == 0) {
17808                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17809                            "*** Enqueueing dispatch processes changed!");
17810                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17811                }
17812                mPendingProcessChanges.add(item);
17813            }
17814            item.changes |= changes;
17815            item.processState = app.repProcState;
17816            item.foregroundActivities = app.repForegroundActivities;
17817            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17818                    + Integer.toHexString(System.identityHashCode(item))
17819                    + " " + app.toShortString() + ": changes=" + item.changes
17820                    + " procState=" + item.processState
17821                    + " foreground=" + item.foregroundActivities
17822                    + " type=" + app.adjType + " source=" + app.adjSource
17823                    + " target=" + app.adjTarget);
17824        }
17825
17826        return success;
17827    }
17828
17829    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17830        if (proc.thread != null) {
17831            if (proc.baseProcessTracker != null) {
17832                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17833            }
17834            if (proc.repProcState >= 0) {
17835                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17836                        proc.repProcState);
17837            }
17838        }
17839    }
17840
17841    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17842            ProcessRecord TOP_APP, boolean doingAll, long now) {
17843        if (app.thread == null) {
17844            return false;
17845        }
17846
17847        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17848
17849        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17850    }
17851
17852    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17853            boolean oomAdj) {
17854        if (isForeground != proc.foregroundServices) {
17855            proc.foregroundServices = isForeground;
17856            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17857                    proc.info.uid);
17858            if (isForeground) {
17859                if (curProcs == null) {
17860                    curProcs = new ArrayList<ProcessRecord>();
17861                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17862                }
17863                if (!curProcs.contains(proc)) {
17864                    curProcs.add(proc);
17865                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17866                            proc.info.packageName, proc.info.uid);
17867                }
17868            } else {
17869                if (curProcs != null) {
17870                    if (curProcs.remove(proc)) {
17871                        mBatteryStatsService.noteEvent(
17872                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17873                                proc.info.packageName, proc.info.uid);
17874                        if (curProcs.size() <= 0) {
17875                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17876                        }
17877                    }
17878                }
17879            }
17880            if (oomAdj) {
17881                updateOomAdjLocked();
17882            }
17883        }
17884    }
17885
17886    private final ActivityRecord resumedAppLocked() {
17887        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17888        String pkg;
17889        int uid;
17890        if (act != null) {
17891            pkg = act.packageName;
17892            uid = act.info.applicationInfo.uid;
17893        } else {
17894            pkg = null;
17895            uid = -1;
17896        }
17897        // Has the UID or resumed package name changed?
17898        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17899                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17900            if (mCurResumedPackage != null) {
17901                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17902                        mCurResumedPackage, mCurResumedUid);
17903            }
17904            mCurResumedPackage = pkg;
17905            mCurResumedUid = uid;
17906            if (mCurResumedPackage != null) {
17907                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17908                        mCurResumedPackage, mCurResumedUid);
17909            }
17910        }
17911        return act;
17912    }
17913
17914    final boolean updateOomAdjLocked(ProcessRecord app) {
17915        final ActivityRecord TOP_ACT = resumedAppLocked();
17916        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17917        final boolean wasCached = app.cached;
17918
17919        mAdjSeq++;
17920
17921        // This is the desired cached adjusment we want to tell it to use.
17922        // If our app is currently cached, we know it, and that is it.  Otherwise,
17923        // we don't know it yet, and it needs to now be cached we will then
17924        // need to do a complete oom adj.
17925        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17926                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17927        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17928                SystemClock.uptimeMillis());
17929        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17930            // Changed to/from cached state, so apps after it in the LRU
17931            // list may also be changed.
17932            updateOomAdjLocked();
17933        }
17934        return success;
17935    }
17936
17937    final void updateOomAdjLocked() {
17938        final ActivityRecord TOP_ACT = resumedAppLocked();
17939        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17940        final long now = SystemClock.uptimeMillis();
17941        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17942        final int N = mLruProcesses.size();
17943
17944        if (false) {
17945            RuntimeException e = new RuntimeException();
17946            e.fillInStackTrace();
17947            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17948        }
17949
17950        mAdjSeq++;
17951        mNewNumServiceProcs = 0;
17952        mNewNumAServiceProcs = 0;
17953
17954        final int emptyProcessLimit;
17955        final int cachedProcessLimit;
17956        if (mProcessLimit <= 0) {
17957            emptyProcessLimit = cachedProcessLimit = 0;
17958        } else if (mProcessLimit == 1) {
17959            emptyProcessLimit = 1;
17960            cachedProcessLimit = 0;
17961        } else {
17962            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17963            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17964        }
17965
17966        // Let's determine how many processes we have running vs.
17967        // how many slots we have for background processes; we may want
17968        // to put multiple processes in a slot of there are enough of
17969        // them.
17970        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17971                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17972        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17973        if (numEmptyProcs > cachedProcessLimit) {
17974            // If there are more empty processes than our limit on cached
17975            // processes, then use the cached process limit for the factor.
17976            // This ensures that the really old empty processes get pushed
17977            // down to the bottom, so if we are running low on memory we will
17978            // have a better chance at keeping around more cached processes
17979            // instead of a gazillion empty processes.
17980            numEmptyProcs = cachedProcessLimit;
17981        }
17982        int emptyFactor = numEmptyProcs/numSlots;
17983        if (emptyFactor < 1) emptyFactor = 1;
17984        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17985        if (cachedFactor < 1) cachedFactor = 1;
17986        int stepCached = 0;
17987        int stepEmpty = 0;
17988        int numCached = 0;
17989        int numEmpty = 0;
17990        int numTrimming = 0;
17991
17992        mNumNonCachedProcs = 0;
17993        mNumCachedHiddenProcs = 0;
17994
17995        // First update the OOM adjustment for each of the
17996        // application processes based on their current state.
17997        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17998        int nextCachedAdj = curCachedAdj+1;
17999        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18000        int nextEmptyAdj = curEmptyAdj+2;
18001        for (int i=N-1; i>=0; i--) {
18002            ProcessRecord app = mLruProcesses.get(i);
18003            if (!app.killedByAm && app.thread != null) {
18004                app.procStateChanged = false;
18005                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18006
18007                // If we haven't yet assigned the final cached adj
18008                // to the process, do that now.
18009                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18010                    switch (app.curProcState) {
18011                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18012                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18013                            // This process is a cached process holding activities...
18014                            // assign it the next cached value for that type, and then
18015                            // step that cached level.
18016                            app.curRawAdj = curCachedAdj;
18017                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18018                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18019                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18020                                    + ")");
18021                            if (curCachedAdj != nextCachedAdj) {
18022                                stepCached++;
18023                                if (stepCached >= cachedFactor) {
18024                                    stepCached = 0;
18025                                    curCachedAdj = nextCachedAdj;
18026                                    nextCachedAdj += 2;
18027                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18028                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18029                                    }
18030                                }
18031                            }
18032                            break;
18033                        default:
18034                            // For everything else, assign next empty cached process
18035                            // level and bump that up.  Note that this means that
18036                            // long-running services that have dropped down to the
18037                            // cached level will be treated as empty (since their process
18038                            // state is still as a service), which is what we want.
18039                            app.curRawAdj = curEmptyAdj;
18040                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18041                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18042                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18043                                    + ")");
18044                            if (curEmptyAdj != nextEmptyAdj) {
18045                                stepEmpty++;
18046                                if (stepEmpty >= emptyFactor) {
18047                                    stepEmpty = 0;
18048                                    curEmptyAdj = nextEmptyAdj;
18049                                    nextEmptyAdj += 2;
18050                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18051                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18052                                    }
18053                                }
18054                            }
18055                            break;
18056                    }
18057                }
18058
18059                applyOomAdjLocked(app, TOP_APP, true, now);
18060
18061                // Count the number of process types.
18062                switch (app.curProcState) {
18063                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18064                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18065                        mNumCachedHiddenProcs++;
18066                        numCached++;
18067                        if (numCached > cachedProcessLimit) {
18068                            app.kill("cached #" + numCached, true);
18069                        }
18070                        break;
18071                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18072                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18073                                && app.lastActivityTime < oldTime) {
18074                            app.kill("empty for "
18075                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18076                                    / 1000) + "s", true);
18077                        } else {
18078                            numEmpty++;
18079                            if (numEmpty > emptyProcessLimit) {
18080                                app.kill("empty #" + numEmpty, true);
18081                            }
18082                        }
18083                        break;
18084                    default:
18085                        mNumNonCachedProcs++;
18086                        break;
18087                }
18088
18089                if (app.isolated && app.services.size() <= 0) {
18090                    // If this is an isolated process, and there are no
18091                    // services running in it, then the process is no longer
18092                    // needed.  We agressively kill these because we can by
18093                    // definition not re-use the same process again, and it is
18094                    // good to avoid having whatever code was running in them
18095                    // left sitting around after no longer needed.
18096                    app.kill("isolated not needed", true);
18097                }
18098
18099                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18100                        && !app.killedByAm) {
18101                    numTrimming++;
18102                }
18103            }
18104        }
18105
18106        mNumServiceProcs = mNewNumServiceProcs;
18107
18108        // Now determine the memory trimming level of background processes.
18109        // Unfortunately we need to start at the back of the list to do this
18110        // properly.  We only do this if the number of background apps we
18111        // are managing to keep around is less than half the maximum we desire;
18112        // if we are keeping a good number around, we'll let them use whatever
18113        // memory they want.
18114        final int numCachedAndEmpty = numCached + numEmpty;
18115        int memFactor;
18116        if (numCached <= ProcessList.TRIM_CACHED_APPS
18117                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18118            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18119                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18120            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18121                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18122            } else {
18123                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18124            }
18125        } else {
18126            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18127        }
18128        // We always allow the memory level to go up (better).  We only allow it to go
18129        // down if we are in a state where that is allowed, *and* the total number of processes
18130        // has gone down since last time.
18131        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18132                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18133                + " last=" + mLastNumProcesses);
18134        if (memFactor > mLastMemoryLevel) {
18135            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18136                memFactor = mLastMemoryLevel;
18137                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18138            }
18139        }
18140        mLastMemoryLevel = memFactor;
18141        mLastNumProcesses = mLruProcesses.size();
18142        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18143        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18144        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18145            if (mLowRamStartTime == 0) {
18146                mLowRamStartTime = now;
18147            }
18148            int step = 0;
18149            int fgTrimLevel;
18150            switch (memFactor) {
18151                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18152                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18153                    break;
18154                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18155                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18156                    break;
18157                default:
18158                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18159                    break;
18160            }
18161            int factor = numTrimming/3;
18162            int minFactor = 2;
18163            if (mHomeProcess != null) minFactor++;
18164            if (mPreviousProcess != null) minFactor++;
18165            if (factor < minFactor) factor = minFactor;
18166            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18167            for (int i=N-1; i>=0; i--) {
18168                ProcessRecord app = mLruProcesses.get(i);
18169                if (allChanged || app.procStateChanged) {
18170                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18171                    app.procStateChanged = false;
18172                }
18173                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18174                        && !app.killedByAm) {
18175                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18176                        try {
18177                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18178                                    "Trimming memory of " + app.processName
18179                                    + " to " + curLevel);
18180                            app.thread.scheduleTrimMemory(curLevel);
18181                        } catch (RemoteException e) {
18182                        }
18183                        if (false) {
18184                            // For now we won't do this; our memory trimming seems
18185                            // to be good enough at this point that destroying
18186                            // activities causes more harm than good.
18187                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18188                                    && app != mHomeProcess && app != mPreviousProcess) {
18189                                // Need to do this on its own message because the stack may not
18190                                // be in a consistent state at this point.
18191                                // For these apps we will also finish their activities
18192                                // to help them free memory.
18193                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18194                            }
18195                        }
18196                    }
18197                    app.trimMemoryLevel = curLevel;
18198                    step++;
18199                    if (step >= factor) {
18200                        step = 0;
18201                        switch (curLevel) {
18202                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18203                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18204                                break;
18205                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18206                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18207                                break;
18208                        }
18209                    }
18210                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18211                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18212                            && app.thread != null) {
18213                        try {
18214                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18215                                    "Trimming memory of heavy-weight " + app.processName
18216                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18217                            app.thread.scheduleTrimMemory(
18218                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18219                        } catch (RemoteException e) {
18220                        }
18221                    }
18222                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18223                } else {
18224                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18225                            || app.systemNoUi) && app.pendingUiClean) {
18226                        // If this application is now in the background and it
18227                        // had done UI, then give it the special trim level to
18228                        // have it free UI resources.
18229                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18230                        if (app.trimMemoryLevel < level && app.thread != null) {
18231                            try {
18232                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18233                                        "Trimming memory of bg-ui " + app.processName
18234                                        + " to " + level);
18235                                app.thread.scheduleTrimMemory(level);
18236                            } catch (RemoteException e) {
18237                            }
18238                        }
18239                        app.pendingUiClean = false;
18240                    }
18241                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18242                        try {
18243                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18244                                    "Trimming memory of fg " + app.processName
18245                                    + " to " + fgTrimLevel);
18246                            app.thread.scheduleTrimMemory(fgTrimLevel);
18247                        } catch (RemoteException e) {
18248                        }
18249                    }
18250                    app.trimMemoryLevel = fgTrimLevel;
18251                }
18252            }
18253        } else {
18254            if (mLowRamStartTime != 0) {
18255                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18256                mLowRamStartTime = 0;
18257            }
18258            for (int i=N-1; i>=0; i--) {
18259                ProcessRecord app = mLruProcesses.get(i);
18260                if (allChanged || app.procStateChanged) {
18261                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18262                    app.procStateChanged = false;
18263                }
18264                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18265                        || app.systemNoUi) && app.pendingUiClean) {
18266                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18267                            && app.thread != null) {
18268                        try {
18269                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18270                                    "Trimming memory of ui hidden " + app.processName
18271                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18272                            app.thread.scheduleTrimMemory(
18273                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18274                        } catch (RemoteException e) {
18275                        }
18276                    }
18277                    app.pendingUiClean = false;
18278                }
18279                app.trimMemoryLevel = 0;
18280            }
18281        }
18282
18283        if (mAlwaysFinishActivities) {
18284            // Need to do this on its own message because the stack may not
18285            // be in a consistent state at this point.
18286            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18287        }
18288
18289        if (allChanged) {
18290            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18291        }
18292
18293        if (mProcessStats.shouldWriteNowLocked(now)) {
18294            mHandler.post(new Runnable() {
18295                @Override public void run() {
18296                    synchronized (ActivityManagerService.this) {
18297                        mProcessStats.writeStateAsyncLocked();
18298                    }
18299                }
18300            });
18301        }
18302
18303        if (DEBUG_OOM_ADJ) {
18304            if (false) {
18305                RuntimeException here = new RuntimeException("here");
18306                here.fillInStackTrace();
18307                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18308            } else {
18309                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18310            }
18311        }
18312    }
18313
18314    final void trimApplications() {
18315        synchronized (this) {
18316            int i;
18317
18318            // First remove any unused application processes whose package
18319            // has been removed.
18320            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18321                final ProcessRecord app = mRemovedProcesses.get(i);
18322                if (app.activities.size() == 0
18323                        && app.curReceiver == null && app.services.size() == 0) {
18324                    Slog.i(
18325                        TAG, "Exiting empty application process "
18326                        + app.processName + " ("
18327                        + (app.thread != null ? app.thread.asBinder() : null)
18328                        + ")\n");
18329                    if (app.pid > 0 && app.pid != MY_PID) {
18330                        app.kill("empty", false);
18331                    } else {
18332                        try {
18333                            app.thread.scheduleExit();
18334                        } catch (Exception e) {
18335                            // Ignore exceptions.
18336                        }
18337                    }
18338                    cleanUpApplicationRecordLocked(app, false, true, -1);
18339                    mRemovedProcesses.remove(i);
18340
18341                    if (app.persistent) {
18342                        addAppLocked(app.info, false, null /* ABI override */);
18343                    }
18344                }
18345            }
18346
18347            // Now update the oom adj for all processes.
18348            updateOomAdjLocked();
18349        }
18350    }
18351
18352    /** This method sends the specified signal to each of the persistent apps */
18353    public void signalPersistentProcesses(int sig) throws RemoteException {
18354        if (sig != Process.SIGNAL_USR1) {
18355            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18356        }
18357
18358        synchronized (this) {
18359            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18360                    != PackageManager.PERMISSION_GRANTED) {
18361                throw new SecurityException("Requires permission "
18362                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18363            }
18364
18365            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18366                ProcessRecord r = mLruProcesses.get(i);
18367                if (r.thread != null && r.persistent) {
18368                    Process.sendSignal(r.pid, sig);
18369                }
18370            }
18371        }
18372    }
18373
18374    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18375        if (proc == null || proc == mProfileProc) {
18376            proc = mProfileProc;
18377            profileType = mProfileType;
18378            clearProfilerLocked();
18379        }
18380        if (proc == null) {
18381            return;
18382        }
18383        try {
18384            proc.thread.profilerControl(false, null, profileType);
18385        } catch (RemoteException e) {
18386            throw new IllegalStateException("Process disappeared");
18387        }
18388    }
18389
18390    private void clearProfilerLocked() {
18391        if (mProfileFd != null) {
18392            try {
18393                mProfileFd.close();
18394            } catch (IOException e) {
18395            }
18396        }
18397        mProfileApp = null;
18398        mProfileProc = null;
18399        mProfileFile = null;
18400        mProfileType = 0;
18401        mAutoStopProfiler = false;
18402        mSamplingInterval = 0;
18403    }
18404
18405    public boolean profileControl(String process, int userId, boolean start,
18406            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18407
18408        try {
18409            synchronized (this) {
18410                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18411                // its own permission.
18412                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18413                        != PackageManager.PERMISSION_GRANTED) {
18414                    throw new SecurityException("Requires permission "
18415                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18416                }
18417
18418                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18419                    throw new IllegalArgumentException("null profile info or fd");
18420                }
18421
18422                ProcessRecord proc = null;
18423                if (process != null) {
18424                    proc = findProcessLocked(process, userId, "profileControl");
18425                }
18426
18427                if (start && (proc == null || proc.thread == null)) {
18428                    throw new IllegalArgumentException("Unknown process: " + process);
18429                }
18430
18431                if (start) {
18432                    stopProfilerLocked(null, 0);
18433                    setProfileApp(proc.info, proc.processName, profilerInfo);
18434                    mProfileProc = proc;
18435                    mProfileType = profileType;
18436                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18437                    try {
18438                        fd = fd.dup();
18439                    } catch (IOException e) {
18440                        fd = null;
18441                    }
18442                    profilerInfo.profileFd = fd;
18443                    proc.thread.profilerControl(start, profilerInfo, profileType);
18444                    fd = null;
18445                    mProfileFd = null;
18446                } else {
18447                    stopProfilerLocked(proc, profileType);
18448                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18449                        try {
18450                            profilerInfo.profileFd.close();
18451                        } catch (IOException e) {
18452                        }
18453                    }
18454                }
18455
18456                return true;
18457            }
18458        } catch (RemoteException e) {
18459            throw new IllegalStateException("Process disappeared");
18460        } finally {
18461            if (profilerInfo != null && profilerInfo.profileFd != null) {
18462                try {
18463                    profilerInfo.profileFd.close();
18464                } catch (IOException e) {
18465                }
18466            }
18467        }
18468    }
18469
18470    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18471        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18472                userId, true, ALLOW_FULL_ONLY, callName, null);
18473        ProcessRecord proc = null;
18474        try {
18475            int pid = Integer.parseInt(process);
18476            synchronized (mPidsSelfLocked) {
18477                proc = mPidsSelfLocked.get(pid);
18478            }
18479        } catch (NumberFormatException e) {
18480        }
18481
18482        if (proc == null) {
18483            ArrayMap<String, SparseArray<ProcessRecord>> all
18484                    = mProcessNames.getMap();
18485            SparseArray<ProcessRecord> procs = all.get(process);
18486            if (procs != null && procs.size() > 0) {
18487                proc = procs.valueAt(0);
18488                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18489                    for (int i=1; i<procs.size(); i++) {
18490                        ProcessRecord thisProc = procs.valueAt(i);
18491                        if (thisProc.userId == userId) {
18492                            proc = thisProc;
18493                            break;
18494                        }
18495                    }
18496                }
18497            }
18498        }
18499
18500        return proc;
18501    }
18502
18503    public boolean dumpHeap(String process, int userId, boolean managed,
18504            String path, ParcelFileDescriptor fd) throws RemoteException {
18505
18506        try {
18507            synchronized (this) {
18508                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18509                // its own permission (same as profileControl).
18510                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18511                        != PackageManager.PERMISSION_GRANTED) {
18512                    throw new SecurityException("Requires permission "
18513                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18514                }
18515
18516                if (fd == null) {
18517                    throw new IllegalArgumentException("null fd");
18518                }
18519
18520                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18521                if (proc == null || proc.thread == null) {
18522                    throw new IllegalArgumentException("Unknown process: " + process);
18523                }
18524
18525                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18526                if (!isDebuggable) {
18527                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18528                        throw new SecurityException("Process not debuggable: " + proc);
18529                    }
18530                }
18531
18532                proc.thread.dumpHeap(managed, path, fd);
18533                fd = null;
18534                return true;
18535            }
18536        } catch (RemoteException e) {
18537            throw new IllegalStateException("Process disappeared");
18538        } finally {
18539            if (fd != null) {
18540                try {
18541                    fd.close();
18542                } catch (IOException e) {
18543                }
18544            }
18545        }
18546    }
18547
18548    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18549    public void monitor() {
18550        synchronized (this) { }
18551    }
18552
18553    void onCoreSettingsChange(Bundle settings) {
18554        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18555            ProcessRecord processRecord = mLruProcesses.get(i);
18556            try {
18557                if (processRecord.thread != null) {
18558                    processRecord.thread.setCoreSettings(settings);
18559                }
18560            } catch (RemoteException re) {
18561                /* ignore */
18562            }
18563        }
18564    }
18565
18566    // Multi-user methods
18567
18568    /**
18569     * Start user, if its not already running, but don't bring it to foreground.
18570     */
18571    @Override
18572    public boolean startUserInBackground(final int userId) {
18573        return startUser(userId, /* foreground */ false);
18574    }
18575
18576    /**
18577     * Start user, if its not already running, and bring it to foreground.
18578     */
18579    boolean startUserInForeground(final int userId, Dialog dlg) {
18580        boolean result = startUser(userId, /* foreground */ true);
18581        dlg.dismiss();
18582        return result;
18583    }
18584
18585    /**
18586     * Refreshes the list of users related to the current user when either a
18587     * user switch happens or when a new related user is started in the
18588     * background.
18589     */
18590    private void updateCurrentProfileIdsLocked() {
18591        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18592                mCurrentUserId, false /* enabledOnly */);
18593        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18594        for (int i = 0; i < currentProfileIds.length; i++) {
18595            currentProfileIds[i] = profiles.get(i).id;
18596        }
18597        mCurrentProfileIds = currentProfileIds;
18598
18599        synchronized (mUserProfileGroupIdsSelfLocked) {
18600            mUserProfileGroupIdsSelfLocked.clear();
18601            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18602            for (int i = 0; i < users.size(); i++) {
18603                UserInfo user = users.get(i);
18604                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18605                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18606                }
18607            }
18608        }
18609    }
18610
18611    private Set getProfileIdsLocked(int userId) {
18612        Set userIds = new HashSet<Integer>();
18613        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18614                userId, false /* enabledOnly */);
18615        for (UserInfo user : profiles) {
18616            userIds.add(Integer.valueOf(user.id));
18617        }
18618        return userIds;
18619    }
18620
18621    @Override
18622    public boolean switchUser(final int userId) {
18623        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18624        String userName;
18625        synchronized (this) {
18626            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18627            if (userInfo == null) {
18628                Slog.w(TAG, "No user info for user #" + userId);
18629                return false;
18630            }
18631            if (userInfo.isManagedProfile()) {
18632                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18633                return false;
18634            }
18635            userName = userInfo.name;
18636            mTargetUserId = userId;
18637        }
18638        mHandler.removeMessages(START_USER_SWITCH_MSG);
18639        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18640        return true;
18641    }
18642
18643    private void showUserSwitchDialog(int userId, String userName) {
18644        // The dialog will show and then initiate the user switch by calling startUserInForeground
18645        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18646                true /* above system */);
18647        d.show();
18648    }
18649
18650    private boolean startUser(final int userId, final boolean foreground) {
18651        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18652                != PackageManager.PERMISSION_GRANTED) {
18653            String msg = "Permission Denial: switchUser() from pid="
18654                    + Binder.getCallingPid()
18655                    + ", uid=" + Binder.getCallingUid()
18656                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18657            Slog.w(TAG, msg);
18658            throw new SecurityException(msg);
18659        }
18660
18661        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18662
18663        final long ident = Binder.clearCallingIdentity();
18664        try {
18665            synchronized (this) {
18666                final int oldUserId = mCurrentUserId;
18667                if (oldUserId == userId) {
18668                    return true;
18669                }
18670
18671                mStackSupervisor.setLockTaskModeLocked(null, false);
18672
18673                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18674                if (userInfo == null) {
18675                    Slog.w(TAG, "No user info for user #" + userId);
18676                    return false;
18677                }
18678                if (foreground && userInfo.isManagedProfile()) {
18679                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18680                    return false;
18681                }
18682
18683                if (foreground) {
18684                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18685                            R.anim.screen_user_enter);
18686                }
18687
18688                boolean needStart = false;
18689
18690                // If the user we are switching to is not currently started, then
18691                // we need to start it now.
18692                if (mStartedUsers.get(userId) == null) {
18693                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18694                    updateStartedUserArrayLocked();
18695                    needStart = true;
18696                }
18697
18698                final Integer userIdInt = Integer.valueOf(userId);
18699                mUserLru.remove(userIdInt);
18700                mUserLru.add(userIdInt);
18701
18702                if (foreground) {
18703                    mCurrentUserId = userId;
18704                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18705                    updateCurrentProfileIdsLocked();
18706                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18707                    // Once the internal notion of the active user has switched, we lock the device
18708                    // with the option to show the user switcher on the keyguard.
18709                    mWindowManager.lockNow(null);
18710                } else {
18711                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18712                    updateCurrentProfileIdsLocked();
18713                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18714                    mUserLru.remove(currentUserIdInt);
18715                    mUserLru.add(currentUserIdInt);
18716                }
18717
18718                final UserStartedState uss = mStartedUsers.get(userId);
18719
18720                // Make sure user is in the started state.  If it is currently
18721                // stopping, we need to knock that off.
18722                if (uss.mState == UserStartedState.STATE_STOPPING) {
18723                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18724                    // so we can just fairly silently bring the user back from
18725                    // the almost-dead.
18726                    uss.mState = UserStartedState.STATE_RUNNING;
18727                    updateStartedUserArrayLocked();
18728                    needStart = true;
18729                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18730                    // This means ACTION_SHUTDOWN has been sent, so we will
18731                    // need to treat this as a new boot of the user.
18732                    uss.mState = UserStartedState.STATE_BOOTING;
18733                    updateStartedUserArrayLocked();
18734                    needStart = true;
18735                }
18736
18737                if (uss.mState == UserStartedState.STATE_BOOTING) {
18738                    // Booting up a new user, need to tell system services about it.
18739                    // Note that this is on the same handler as scheduling of broadcasts,
18740                    // which is important because it needs to go first.
18741                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18742                }
18743
18744                if (foreground) {
18745                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18746                            oldUserId));
18747                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18748                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18749                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18750                            oldUserId, userId, uss));
18751                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18752                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18753                }
18754
18755                if (needStart) {
18756                    // Send USER_STARTED broadcast
18757                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18758                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18759                            | Intent.FLAG_RECEIVER_FOREGROUND);
18760                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18761                    broadcastIntentLocked(null, null, intent,
18762                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18763                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18764                }
18765
18766                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18767                    if (userId != UserHandle.USER_OWNER) {
18768                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18769                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18770                        broadcastIntentLocked(null, null, intent, null,
18771                                new IIntentReceiver.Stub() {
18772                                    public void performReceive(Intent intent, int resultCode,
18773                                            String data, Bundle extras, boolean ordered,
18774                                            boolean sticky, int sendingUser) {
18775                                        onUserInitialized(uss, foreground, oldUserId, userId);
18776                                    }
18777                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18778                                true, false, MY_PID, Process.SYSTEM_UID,
18779                                userId);
18780                        uss.initializing = true;
18781                    } else {
18782                        getUserManagerLocked().makeInitialized(userInfo.id);
18783                    }
18784                }
18785
18786                if (foreground) {
18787                    if (!uss.initializing) {
18788                        moveUserToForeground(uss, oldUserId, userId);
18789                    }
18790                } else {
18791                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18792                }
18793
18794                if (needStart) {
18795                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18796                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18797                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18798                    broadcastIntentLocked(null, null, intent,
18799                            null, new IIntentReceiver.Stub() {
18800                                @Override
18801                                public void performReceive(Intent intent, int resultCode, String data,
18802                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18803                                        throws RemoteException {
18804                                }
18805                            }, 0, null, null,
18806                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18807                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18808                }
18809            }
18810        } finally {
18811            Binder.restoreCallingIdentity(ident);
18812        }
18813
18814        return true;
18815    }
18816
18817    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18818        long ident = Binder.clearCallingIdentity();
18819        try {
18820            Intent intent;
18821            if (oldUserId >= 0) {
18822                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18823                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18824                int count = profiles.size();
18825                for (int i = 0; i < count; i++) {
18826                    int profileUserId = profiles.get(i).id;
18827                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18828                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18829                            | Intent.FLAG_RECEIVER_FOREGROUND);
18830                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18831                    broadcastIntentLocked(null, null, intent,
18832                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18833                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18834                }
18835            }
18836            if (newUserId >= 0) {
18837                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18838                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18839                int count = profiles.size();
18840                for (int i = 0; i < count; i++) {
18841                    int profileUserId = profiles.get(i).id;
18842                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18843                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18844                            | Intent.FLAG_RECEIVER_FOREGROUND);
18845                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18846                    broadcastIntentLocked(null, null, intent,
18847                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18848                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18849                }
18850                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18851                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18852                        | Intent.FLAG_RECEIVER_FOREGROUND);
18853                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18854                broadcastIntentLocked(null, null, intent,
18855                        null, null, 0, null, null,
18856                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18857                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18858            }
18859        } finally {
18860            Binder.restoreCallingIdentity(ident);
18861        }
18862    }
18863
18864    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18865            final int newUserId) {
18866        final int N = mUserSwitchObservers.beginBroadcast();
18867        if (N > 0) {
18868            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18869                int mCount = 0;
18870                @Override
18871                public void sendResult(Bundle data) throws RemoteException {
18872                    synchronized (ActivityManagerService.this) {
18873                        if (mCurUserSwitchCallback == this) {
18874                            mCount++;
18875                            if (mCount == N) {
18876                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18877                            }
18878                        }
18879                    }
18880                }
18881            };
18882            synchronized (this) {
18883                uss.switching = true;
18884                mCurUserSwitchCallback = callback;
18885            }
18886            for (int i=0; i<N; i++) {
18887                try {
18888                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18889                            newUserId, callback);
18890                } catch (RemoteException e) {
18891                }
18892            }
18893        } else {
18894            synchronized (this) {
18895                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18896            }
18897        }
18898        mUserSwitchObservers.finishBroadcast();
18899    }
18900
18901    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18902        synchronized (this) {
18903            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18904            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18905        }
18906    }
18907
18908    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18909        mCurUserSwitchCallback = null;
18910        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18911        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18912                oldUserId, newUserId, uss));
18913    }
18914
18915    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18916        synchronized (this) {
18917            if (foreground) {
18918                moveUserToForeground(uss, oldUserId, newUserId);
18919            }
18920        }
18921
18922        completeSwitchAndInitalize(uss, newUserId, true, false);
18923    }
18924
18925    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18926        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18927        if (homeInFront) {
18928            startHomeActivityLocked(newUserId);
18929        } else {
18930            mStackSupervisor.resumeTopActivitiesLocked();
18931        }
18932        EventLogTags.writeAmSwitchUser(newUserId);
18933        getUserManagerLocked().userForeground(newUserId);
18934        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18935    }
18936
18937    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18938        completeSwitchAndInitalize(uss, newUserId, false, true);
18939    }
18940
18941    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18942            boolean clearInitializing, boolean clearSwitching) {
18943        boolean unfrozen = false;
18944        synchronized (this) {
18945            if (clearInitializing) {
18946                uss.initializing = false;
18947                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18948            }
18949            if (clearSwitching) {
18950                uss.switching = false;
18951            }
18952            if (!uss.switching && !uss.initializing) {
18953                mWindowManager.stopFreezingScreen();
18954                unfrozen = true;
18955            }
18956        }
18957        if (unfrozen) {
18958            final int N = mUserSwitchObservers.beginBroadcast();
18959            for (int i=0; i<N; i++) {
18960                try {
18961                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18962                } catch (RemoteException e) {
18963                }
18964            }
18965            mUserSwitchObservers.finishBroadcast();
18966        }
18967        stopGuestUserIfBackground();
18968    }
18969
18970    /**
18971     * Stops the guest user if it has gone to the background.
18972     */
18973    private void stopGuestUserIfBackground() {
18974        synchronized (this) {
18975            final int num = mUserLru.size();
18976            for (int i = 0; i < num; i++) {
18977                Integer oldUserId = mUserLru.get(i);
18978                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18979                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18980                        || oldUss.mState == UserStartedState.STATE_STOPPING
18981                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18982                    continue;
18983                }
18984                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18985                if (userInfo.isGuest()) {
18986                    // This is a user to be stopped.
18987                    stopUserLocked(oldUserId, null);
18988                    break;
18989                }
18990            }
18991        }
18992    }
18993
18994    void scheduleStartProfilesLocked() {
18995        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18996            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18997                    DateUtils.SECOND_IN_MILLIS);
18998        }
18999    }
19000
19001    void startProfilesLocked() {
19002        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19003        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19004                mCurrentUserId, false /* enabledOnly */);
19005        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19006        for (UserInfo user : profiles) {
19007            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19008                    && user.id != mCurrentUserId) {
19009                toStart.add(user);
19010            }
19011        }
19012        final int n = toStart.size();
19013        int i = 0;
19014        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19015            startUserInBackground(toStart.get(i).id);
19016        }
19017        if (i < n) {
19018            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19019        }
19020    }
19021
19022    void finishUserBoot(UserStartedState uss) {
19023        synchronized (this) {
19024            if (uss.mState == UserStartedState.STATE_BOOTING
19025                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19026                uss.mState = UserStartedState.STATE_RUNNING;
19027                final int userId = uss.mHandle.getIdentifier();
19028                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19029                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19030                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19031                broadcastIntentLocked(null, null, intent,
19032                        null, null, 0, null, null,
19033                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19034                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19035            }
19036        }
19037    }
19038
19039    void finishUserSwitch(UserStartedState uss) {
19040        synchronized (this) {
19041            finishUserBoot(uss);
19042
19043            startProfilesLocked();
19044
19045            int num = mUserLru.size();
19046            int i = 0;
19047            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19048                Integer oldUserId = mUserLru.get(i);
19049                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19050                if (oldUss == null) {
19051                    // Shouldn't happen, but be sane if it does.
19052                    mUserLru.remove(i);
19053                    num--;
19054                    continue;
19055                }
19056                if (oldUss.mState == UserStartedState.STATE_STOPPING
19057                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19058                    // This user is already stopping, doesn't count.
19059                    num--;
19060                    i++;
19061                    continue;
19062                }
19063                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19064                    // Owner and current can't be stopped, but count as running.
19065                    i++;
19066                    continue;
19067                }
19068                // This is a user to be stopped.
19069                stopUserLocked(oldUserId, null);
19070                num--;
19071                i++;
19072            }
19073        }
19074    }
19075
19076    @Override
19077    public int stopUser(final int userId, final IStopUserCallback callback) {
19078        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19079                != PackageManager.PERMISSION_GRANTED) {
19080            String msg = "Permission Denial: switchUser() from pid="
19081                    + Binder.getCallingPid()
19082                    + ", uid=" + Binder.getCallingUid()
19083                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19084            Slog.w(TAG, msg);
19085            throw new SecurityException(msg);
19086        }
19087        if (userId <= 0) {
19088            throw new IllegalArgumentException("Can't stop primary user " + userId);
19089        }
19090        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19091        synchronized (this) {
19092            return stopUserLocked(userId, callback);
19093        }
19094    }
19095
19096    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19097        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19098        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19099            return ActivityManager.USER_OP_IS_CURRENT;
19100        }
19101
19102        final UserStartedState uss = mStartedUsers.get(userId);
19103        if (uss == null) {
19104            // User is not started, nothing to do...  but we do need to
19105            // callback if requested.
19106            if (callback != null) {
19107                mHandler.post(new Runnable() {
19108                    @Override
19109                    public void run() {
19110                        try {
19111                            callback.userStopped(userId);
19112                        } catch (RemoteException e) {
19113                        }
19114                    }
19115                });
19116            }
19117            return ActivityManager.USER_OP_SUCCESS;
19118        }
19119
19120        if (callback != null) {
19121            uss.mStopCallbacks.add(callback);
19122        }
19123
19124        if (uss.mState != UserStartedState.STATE_STOPPING
19125                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19126            uss.mState = UserStartedState.STATE_STOPPING;
19127            updateStartedUserArrayLocked();
19128
19129            long ident = Binder.clearCallingIdentity();
19130            try {
19131                // We are going to broadcast ACTION_USER_STOPPING and then
19132                // once that is done send a final ACTION_SHUTDOWN and then
19133                // stop the user.
19134                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19135                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19136                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19137                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19138                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19139                // This is the result receiver for the final shutdown broadcast.
19140                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19141                    @Override
19142                    public void performReceive(Intent intent, int resultCode, String data,
19143                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19144                        finishUserStop(uss);
19145                    }
19146                };
19147                // This is the result receiver for the initial stopping broadcast.
19148                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19149                    @Override
19150                    public void performReceive(Intent intent, int resultCode, String data,
19151                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19152                        // On to the next.
19153                        synchronized (ActivityManagerService.this) {
19154                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19155                                // Whoops, we are being started back up.  Abort, abort!
19156                                return;
19157                            }
19158                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19159                        }
19160                        mBatteryStatsService.noteEvent(
19161                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19162                                Integer.toString(userId), userId);
19163                        mSystemServiceManager.stopUser(userId);
19164                        broadcastIntentLocked(null, null, shutdownIntent,
19165                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19166                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19167                    }
19168                };
19169                // Kick things off.
19170                broadcastIntentLocked(null, null, stoppingIntent,
19171                        null, stoppingReceiver, 0, null, null,
19172                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19173                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19174            } finally {
19175                Binder.restoreCallingIdentity(ident);
19176            }
19177        }
19178
19179        return ActivityManager.USER_OP_SUCCESS;
19180    }
19181
19182    void finishUserStop(UserStartedState uss) {
19183        final int userId = uss.mHandle.getIdentifier();
19184        boolean stopped;
19185        ArrayList<IStopUserCallback> callbacks;
19186        synchronized (this) {
19187            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19188            if (mStartedUsers.get(userId) != uss) {
19189                stopped = false;
19190            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19191                stopped = false;
19192            } else {
19193                stopped = true;
19194                // User can no longer run.
19195                mStartedUsers.remove(userId);
19196                mUserLru.remove(Integer.valueOf(userId));
19197                updateStartedUserArrayLocked();
19198
19199                // Clean up all state and processes associated with the user.
19200                // Kill all the processes for the user.
19201                forceStopUserLocked(userId, "finish user");
19202            }
19203
19204            // Explicitly remove the old information in mRecentTasks.
19205            removeRecentTasksForUserLocked(userId);
19206        }
19207
19208        for (int i=0; i<callbacks.size(); i++) {
19209            try {
19210                if (stopped) callbacks.get(i).userStopped(userId);
19211                else callbacks.get(i).userStopAborted(userId);
19212            } catch (RemoteException e) {
19213            }
19214        }
19215
19216        if (stopped) {
19217            mSystemServiceManager.cleanupUser(userId);
19218            synchronized (this) {
19219                mStackSupervisor.removeUserLocked(userId);
19220            }
19221        }
19222    }
19223
19224    @Override
19225    public UserInfo getCurrentUser() {
19226        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19227                != PackageManager.PERMISSION_GRANTED) && (
19228                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19229                != PackageManager.PERMISSION_GRANTED)) {
19230            String msg = "Permission Denial: getCurrentUser() from pid="
19231                    + Binder.getCallingPid()
19232                    + ", uid=" + Binder.getCallingUid()
19233                    + " requires " + INTERACT_ACROSS_USERS;
19234            Slog.w(TAG, msg);
19235            throw new SecurityException(msg);
19236        }
19237        synchronized (this) {
19238            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19239            return getUserManagerLocked().getUserInfo(userId);
19240        }
19241    }
19242
19243    int getCurrentUserIdLocked() {
19244        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19245    }
19246
19247    @Override
19248    public boolean isUserRunning(int userId, boolean orStopped) {
19249        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19250                != PackageManager.PERMISSION_GRANTED) {
19251            String msg = "Permission Denial: isUserRunning() from pid="
19252                    + Binder.getCallingPid()
19253                    + ", uid=" + Binder.getCallingUid()
19254                    + " requires " + INTERACT_ACROSS_USERS;
19255            Slog.w(TAG, msg);
19256            throw new SecurityException(msg);
19257        }
19258        synchronized (this) {
19259            return isUserRunningLocked(userId, orStopped);
19260        }
19261    }
19262
19263    boolean isUserRunningLocked(int userId, boolean orStopped) {
19264        UserStartedState state = mStartedUsers.get(userId);
19265        if (state == null) {
19266            return false;
19267        }
19268        if (orStopped) {
19269            return true;
19270        }
19271        return state.mState != UserStartedState.STATE_STOPPING
19272                && state.mState != UserStartedState.STATE_SHUTDOWN;
19273    }
19274
19275    @Override
19276    public int[] getRunningUserIds() {
19277        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19278                != PackageManager.PERMISSION_GRANTED) {
19279            String msg = "Permission Denial: isUserRunning() from pid="
19280                    + Binder.getCallingPid()
19281                    + ", uid=" + Binder.getCallingUid()
19282                    + " requires " + INTERACT_ACROSS_USERS;
19283            Slog.w(TAG, msg);
19284            throw new SecurityException(msg);
19285        }
19286        synchronized (this) {
19287            return mStartedUserArray;
19288        }
19289    }
19290
19291    private void updateStartedUserArrayLocked() {
19292        int num = 0;
19293        for (int i=0; i<mStartedUsers.size();  i++) {
19294            UserStartedState uss = mStartedUsers.valueAt(i);
19295            // This list does not include stopping users.
19296            if (uss.mState != UserStartedState.STATE_STOPPING
19297                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19298                num++;
19299            }
19300        }
19301        mStartedUserArray = new int[num];
19302        num = 0;
19303        for (int i=0; i<mStartedUsers.size();  i++) {
19304            UserStartedState uss = mStartedUsers.valueAt(i);
19305            if (uss.mState != UserStartedState.STATE_STOPPING
19306                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19307                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19308                num++;
19309            }
19310        }
19311    }
19312
19313    @Override
19314    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19315        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19316                != PackageManager.PERMISSION_GRANTED) {
19317            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19318                    + Binder.getCallingPid()
19319                    + ", uid=" + Binder.getCallingUid()
19320                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19321            Slog.w(TAG, msg);
19322            throw new SecurityException(msg);
19323        }
19324
19325        mUserSwitchObservers.register(observer);
19326    }
19327
19328    @Override
19329    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19330        mUserSwitchObservers.unregister(observer);
19331    }
19332
19333    private boolean userExists(int userId) {
19334        if (userId == 0) {
19335            return true;
19336        }
19337        UserManagerService ums = getUserManagerLocked();
19338        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19339    }
19340
19341    int[] getUsersLocked() {
19342        UserManagerService ums = getUserManagerLocked();
19343        return ums != null ? ums.getUserIds() : new int[] { 0 };
19344    }
19345
19346    UserManagerService getUserManagerLocked() {
19347        if (mUserManager == null) {
19348            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19349            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19350        }
19351        return mUserManager;
19352    }
19353
19354    private int applyUserId(int uid, int userId) {
19355        return UserHandle.getUid(userId, uid);
19356    }
19357
19358    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19359        if (info == null) return null;
19360        ApplicationInfo newInfo = new ApplicationInfo(info);
19361        newInfo.uid = applyUserId(info.uid, userId);
19362        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19363                + info.packageName;
19364        return newInfo;
19365    }
19366
19367    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19368        if (aInfo == null
19369                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19370            return aInfo;
19371        }
19372
19373        ActivityInfo info = new ActivityInfo(aInfo);
19374        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19375        return info;
19376    }
19377
19378    private final class LocalService extends ActivityManagerInternal {
19379        @Override
19380        public void onWakefulnessChanged(int wakefulness) {
19381            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19382        }
19383
19384        @Override
19385        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19386                String processName, String abiOverride, int uid, Runnable crashHandler) {
19387            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19388                    processName, abiOverride, uid, crashHandler);
19389        }
19390    }
19391
19392    /**
19393     * An implementation of IAppTask, that allows an app to manage its own tasks via
19394     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19395     * only the process that calls getAppTasks() can call the AppTask methods.
19396     */
19397    class AppTaskImpl extends IAppTask.Stub {
19398        private int mTaskId;
19399        private int mCallingUid;
19400
19401        public AppTaskImpl(int taskId, int callingUid) {
19402            mTaskId = taskId;
19403            mCallingUid = callingUid;
19404        }
19405
19406        private void checkCaller() {
19407            if (mCallingUid != Binder.getCallingUid()) {
19408                throw new SecurityException("Caller " + mCallingUid
19409                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19410            }
19411        }
19412
19413        @Override
19414        public void finishAndRemoveTask() {
19415            checkCaller();
19416
19417            synchronized (ActivityManagerService.this) {
19418                long origId = Binder.clearCallingIdentity();
19419                try {
19420                    if (!removeTaskByIdLocked(mTaskId, false)) {
19421                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19422                    }
19423                } finally {
19424                    Binder.restoreCallingIdentity(origId);
19425                }
19426            }
19427        }
19428
19429        @Override
19430        public ActivityManager.RecentTaskInfo getTaskInfo() {
19431            checkCaller();
19432
19433            synchronized (ActivityManagerService.this) {
19434                long origId = Binder.clearCallingIdentity();
19435                try {
19436                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19437                    if (tr == null) {
19438                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19439                    }
19440                    return createRecentTaskInfoFromTaskRecord(tr);
19441                } finally {
19442                    Binder.restoreCallingIdentity(origId);
19443                }
19444            }
19445        }
19446
19447        @Override
19448        public void moveToFront() {
19449            checkCaller();
19450            // Will bring task to front if it already has a root activity.
19451            startActivityFromRecentsInner(mTaskId, null);
19452        }
19453
19454        @Override
19455        public int startActivity(IBinder whoThread, String callingPackage,
19456                Intent intent, String resolvedType, Bundle options) {
19457            checkCaller();
19458
19459            int callingUser = UserHandle.getCallingUserId();
19460            TaskRecord tr;
19461            IApplicationThread appThread;
19462            synchronized (ActivityManagerService.this) {
19463                tr = recentTaskForIdLocked(mTaskId);
19464                if (tr == null) {
19465                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19466                }
19467                appThread = ApplicationThreadNative.asInterface(whoThread);
19468                if (appThread == null) {
19469                    throw new IllegalArgumentException("Bad app thread " + appThread);
19470                }
19471            }
19472            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19473                    resolvedType, null, null, null, null, 0, 0, null, null,
19474                    null, options, callingUser, null, tr);
19475        }
19476
19477        @Override
19478        public void setExcludeFromRecents(boolean exclude) {
19479            checkCaller();
19480
19481            synchronized (ActivityManagerService.this) {
19482                long origId = Binder.clearCallingIdentity();
19483                try {
19484                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19485                    if (tr == null) {
19486                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19487                    }
19488                    Intent intent = tr.getBaseIntent();
19489                    if (exclude) {
19490                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19491                    } else {
19492                        intent.setFlags(intent.getFlags()
19493                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19494                    }
19495                } finally {
19496                    Binder.restoreCallingIdentity(origId);
19497                }
19498            }
19499        }
19500    }
19501}
19502