Home | History | Annotate | Download | only in am
      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 
     17 package com.android.server.am;
     18 
     19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
     20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
     21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
     22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
     24 import static com.android.internal.util.XmlUtils.readIntAttribute;
     25 import static com.android.internal.util.XmlUtils.readLongAttribute;
     26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
     27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
     28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
     29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
     30 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
     33 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
     34 
     35 import android.Manifest;
     36 import android.app.AppOpsManager;
     37 import android.app.ApplicationThreadNative;
     38 import android.app.IActivityContainer;
     39 import android.app.IActivityContainerCallback;
     40 import android.app.IAppTask;
     41 import android.app.ITaskStackListener;
     42 import android.app.ProfilerInfo;
     43 import android.app.admin.DevicePolicyManager;
     44 import android.app.usage.UsageEvents;
     45 import android.app.usage.UsageStatsManagerInternal;
     46 import android.appwidget.AppWidgetManager;
     47 import android.content.res.Resources;
     48 import android.graphics.Bitmap;
     49 import android.graphics.Point;
     50 import android.graphics.Rect;
     51 import android.os.BatteryStats;
     52 import android.os.PersistableBundle;
     53 import android.os.storage.IMountService;
     54 import android.os.storage.StorageManager;
     55 import android.service.voice.IVoiceInteractionSession;
     56 import android.util.ArrayMap;
     57 import android.util.ArraySet;
     58 import android.util.SparseIntArray;
     59 
     60 import android.view.Display;
     61 import com.android.internal.R;
     62 import com.android.internal.annotations.GuardedBy;
     63 import com.android.internal.app.IAppOpsService;
     64 import com.android.internal.app.IVoiceInteractor;
     65 import com.android.internal.app.ProcessMap;
     66 import com.android.internal.app.ProcessStats;
     67 import com.android.internal.os.BackgroundThread;
     68 import com.android.internal.os.BatteryStatsImpl;
     69 import com.android.internal.os.ProcessCpuTracker;
     70 import com.android.internal.os.TransferPipe;
     71 import com.android.internal.os.Zygote;
     72 import com.android.internal.util.FastPrintWriter;
     73 import com.android.internal.util.FastXmlSerializer;
     74 import com.android.internal.util.MemInfoReader;
     75 import com.android.internal.util.Preconditions;
     76 import com.android.server.AppOpsService;
     77 import com.android.server.AttributeCache;
     78 import com.android.server.IntentResolver;
     79 import com.android.server.LocalServices;
     80 import com.android.server.ServiceThread;
     81 import com.android.server.SystemService;
     82 import com.android.server.SystemServiceManager;
     83 import com.android.server.Watchdog;
     84 import com.android.server.am.ActivityStack.ActivityState;
     85 import com.android.server.firewall.IntentFirewall;
     86 import com.android.server.pm.Installer;
     87 import com.android.server.pm.UserManagerService;
     88 import com.android.server.statusbar.StatusBarManagerInternal;
     89 import com.android.server.wm.AppTransition;
     90 import com.android.server.wm.WindowManagerService;
     91 import com.google.android.collect.Lists;
     92 import com.google.android.collect.Maps;
     93 
     94 import libcore.io.IoUtils;
     95 
     96 import org.xmlpull.v1.XmlPullParser;
     97 import org.xmlpull.v1.XmlPullParserException;
     98 import org.xmlpull.v1.XmlSerializer;
     99 
    100 import android.app.Activity;
    101 import android.app.ActivityManager;
    102 import android.app.ActivityManager.RunningTaskInfo;
    103 import android.app.ActivityManager.StackInfo;
    104 import android.app.ActivityManagerInternal;
    105 import android.app.ActivityManagerNative;
    106 import android.app.ActivityOptions;
    107 import android.app.ActivityThread;
    108 import android.app.AlertDialog;
    109 import android.app.AppGlobals;
    110 import android.app.ApplicationErrorReport;
    111 import android.app.Dialog;
    112 import android.app.IActivityController;
    113 import android.app.IApplicationThread;
    114 import android.app.IInstrumentationWatcher;
    115 import android.app.INotificationManager;
    116 import android.app.IProcessObserver;
    117 import android.app.IServiceConnection;
    118 import android.app.IStopUserCallback;
    119 import android.app.IUiAutomationConnection;
    120 import android.app.IUserSwitchObserver;
    121 import android.app.Instrumentation;
    122 import android.app.Notification;
    123 import android.app.NotificationManager;
    124 import android.app.PendingIntent;
    125 import android.app.backup.IBackupManager;
    126 import android.content.ActivityNotFoundException;
    127 import android.content.BroadcastReceiver;
    128 import android.content.ClipData;
    129 import android.content.ComponentCallbacks2;
    130 import android.content.ComponentName;
    131 import android.content.ContentProvider;
    132 import android.content.ContentResolver;
    133 import android.content.Context;
    134 import android.content.DialogInterface;
    135 import android.content.IContentProvider;
    136 import android.content.IIntentReceiver;
    137 import android.content.IIntentSender;
    138 import android.content.Intent;
    139 import android.content.IntentFilter;
    140 import android.content.IntentSender;
    141 import android.content.pm.ActivityInfo;
    142 import android.content.pm.ApplicationInfo;
    143 import android.content.pm.ConfigurationInfo;
    144 import android.content.pm.IPackageDataObserver;
    145 import android.content.pm.IPackageManager;
    146 import android.content.pm.InstrumentationInfo;
    147 import android.content.pm.PackageInfo;
    148 import android.content.pm.PackageManager;
    149 import android.content.pm.ParceledListSlice;
    150 import android.content.pm.UserInfo;
    151 import android.content.pm.PackageManager.NameNotFoundException;
    152 import android.content.pm.PathPermission;
    153 import android.content.pm.ProviderInfo;
    154 import android.content.pm.ResolveInfo;
    155 import android.content.pm.ServiceInfo;
    156 import android.content.res.CompatibilityInfo;
    157 import android.content.res.Configuration;
    158 import android.net.Proxy;
    159 import android.net.ProxyInfo;
    160 import android.net.Uri;
    161 import android.os.Binder;
    162 import android.os.Build;
    163 import android.os.Bundle;
    164 import android.os.Debug;
    165 import android.os.DropBoxManager;
    166 import android.os.Environment;
    167 import android.os.FactoryTest;
    168 import android.os.FileObserver;
    169 import android.os.FileUtils;
    170 import android.os.Handler;
    171 import android.os.IBinder;
    172 import android.os.IPermissionController;
    173 import android.os.IRemoteCallback;
    174 import android.os.IUserManager;
    175 import android.os.Looper;
    176 import android.os.Message;
    177 import android.os.Parcel;
    178 import android.os.ParcelFileDescriptor;
    179 import android.os.PowerManagerInternal;
    180 import android.os.Process;
    181 import android.os.RemoteCallbackList;
    182 import android.os.RemoteException;
    183 import android.os.SELinux;
    184 import android.os.ServiceManager;
    185 import android.os.StrictMode;
    186 import android.os.SystemClock;
    187 import android.os.SystemProperties;
    188 import android.os.UpdateLock;
    189 import android.os.UserHandle;
    190 import android.os.UserManager;
    191 import android.provider.Settings;
    192 import android.text.format.DateUtils;
    193 import android.text.format.Time;
    194 import android.util.AtomicFile;
    195 import android.util.EventLog;
    196 import android.util.Log;
    197 import android.util.Pair;
    198 import android.util.PrintWriterPrinter;
    199 import android.util.Slog;
    200 import android.util.SparseArray;
    201 import android.util.TimeUtils;
    202 import android.util.Xml;
    203 import android.view.Gravity;
    204 import android.view.LayoutInflater;
    205 import android.view.View;
    206 import android.view.WindowManager;
    207 
    208 import dalvik.system.VMRuntime;
    209 
    210 import java.io.BufferedInputStream;
    211 import java.io.BufferedOutputStream;
    212 import java.io.DataInputStream;
    213 import java.io.DataOutputStream;
    214 import java.io.File;
    215 import java.io.FileDescriptor;
    216 import java.io.FileInputStream;
    217 import java.io.FileNotFoundException;
    218 import java.io.FileOutputStream;
    219 import java.io.IOException;
    220 import java.io.InputStreamReader;
    221 import java.io.PrintWriter;
    222 import java.io.StringWriter;
    223 import java.lang.ref.WeakReference;
    224 import java.util.ArrayList;
    225 import java.util.Arrays;
    226 import java.util.Collections;
    227 import java.util.Comparator;
    228 import java.util.HashMap;
    229 import java.util.HashSet;
    230 import java.util.Iterator;
    231 import java.util.List;
    232 import java.util.Locale;
    233 import java.util.Map;
    234 import java.util.Set;
    235 import java.util.concurrent.atomic.AtomicBoolean;
    236 import java.util.concurrent.atomic.AtomicLong;
    237 
    238 public final class ActivityManagerService extends ActivityManagerNative
    239         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    240 
    241     private static final String USER_DATA_DIR = "/data/user/";
    242     // File that stores last updated system version and called preboot receivers
    243     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
    244 
    245     static final String TAG = "ActivityManager";
    246     static final String TAG_MU = "ActivityManagerServiceMU";
    247     static final boolean DEBUG = false;
    248     static final boolean localLOGV = DEBUG;
    249     static final boolean DEBUG_BACKUP = localLOGV || false;
    250     static final boolean DEBUG_BROADCAST = localLOGV || false;
    251     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    252     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    253     static final boolean DEBUG_CLEANUP = localLOGV || false;
    254     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    255     static final boolean DEBUG_FOCUS = false;
    256     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
    257     static final boolean DEBUG_MU = localLOGV || false;
    258     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    259     static final boolean DEBUG_LRU = localLOGV || false;
    260     static final boolean DEBUG_PAUSE = localLOGV || false;
    261     static final boolean DEBUG_POWER = localLOGV || false;
    262     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    263     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    264     static final boolean DEBUG_PROCESSES = localLOGV || false;
    265     static final boolean DEBUG_PROVIDER = localLOGV || false;
    266     static final boolean DEBUG_RESULTS = localLOGV || false;
    267     static final boolean DEBUG_SERVICE = localLOGV || false;
    268     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    269     static final boolean DEBUG_STACK = localLOGV || false;
    270     static final boolean DEBUG_SWITCH = localLOGV || false;
    271     static final boolean DEBUG_TASKS = localLOGV || false;
    272     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    273     static final boolean DEBUG_TRANSITION = localLOGV || false;
    274     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    275     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    276     static final boolean DEBUG_VISBILITY = localLOGV || false;
    277     static final boolean DEBUG_PSS = localLOGV || false;
    278     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
    279     static final boolean DEBUG_RECENTS = localLOGV || false;
    280     static final boolean VALIDATE_TOKENS = false;
    281     static final boolean SHOW_ACTIVITY_START_TIME = true;
    282 
    283     // Control over CPU and battery monitoring.
    284     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    285     static final boolean MONITOR_CPU_USAGE = true;
    286     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    287     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    288     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    289 
    290     // The flags that are set for all calls we make to the package manager.
    291     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    292 
    293     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    294 
    295     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    296 
    297     // Maximum number recent bitmaps to keep in memory.
    298     static final int MAX_RECENT_BITMAPS = 3;
    299 
    300     // Amount of time after a call to stopAppSwitches() during which we will
    301     // prevent further untrusted switches from happening.
    302     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    303 
    304     // How long we wait for a launched process to attach to the activity manager
    305     // before we decide it's never going to come up for real.
    306     static final int PROC_START_TIMEOUT = 10*1000;
    307 
    308     // How long we wait for a launched process to attach to the activity manager
    309     // before we decide it's never going to come up for real, when the process was
    310     // started with a wrapper for instrumentation (such as Valgrind) because it
    311     // could take much longer than usual.
    312     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    313 
    314     // How long to wait after going idle before forcing apps to GC.
    315     static final int GC_TIMEOUT = 5*1000;
    316 
    317     // The minimum amount of time between successive GC requests for a process.
    318     static final int GC_MIN_INTERVAL = 60*1000;
    319 
    320     // The minimum amount of time between successive PSS requests for a process.
    321     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    322 
    323     // The minimum amount of time between successive PSS requests for a process
    324     // when the request is due to the memory state being lowered.
    325     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    326 
    327     // The rate at which we check for apps using excessive power -- 15 mins.
    328     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    329 
    330     // The minimum sample duration we will allow before deciding we have
    331     // enough data on wake locks to start killing things.
    332     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    333 
    334     // The minimum sample duration we will allow before deciding we have
    335     // enough data on CPU usage to start killing things.
    336     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    337 
    338     // How long we allow a receiver to run before giving up on it.
    339     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    340     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    341 
    342     // How long we wait until we timeout on key dispatching.
    343     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    344 
    345     // How long we wait until we timeout on key dispatching during instrumentation.
    346     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    347 
    348     // Amount of time we wait for observers to handle a user switch before
    349     // giving up on them and unfreezing the screen.
    350     static final int USER_SWITCH_TIMEOUT = 2*1000;
    351 
    352     // Maximum number of users we allow to be running at a time.
    353     static final int MAX_RUNNING_USERS = 3;
    354 
    355     // How long to wait in getAssistContextExtras for the activity and foreground services
    356     // to respond with the result.
    357     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    358 
    359     // Maximum number of persisted Uri grants a package is allowed
    360     static final int MAX_PERSISTED_URI_GRANTS = 128;
    361 
    362     static final int MY_PID = Process.myPid();
    363 
    364     static final String[] EMPTY_STRING_ARRAY = new String[0];
    365 
    366     // How many bytes to write into the dropbox log before truncating
    367     static final int DROPBOX_MAX_SIZE = 256 * 1024;
    368 
    369     // Access modes for handleIncomingUser.
    370     static final int ALLOW_NON_FULL = 0;
    371     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    372     static final int ALLOW_FULL_ONLY = 2;
    373 
    374     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
    375 
    376     // Delay in notifying task stack change listeners (in millis)
    377     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
    378 
    379     /** All system services */
    380     SystemServiceManager mSystemServiceManager;
    381 
    382     private Installer mInstaller;
    383 
    384     /** Run all ActivityStacks through this */
    385     ActivityStackSupervisor mStackSupervisor;
    386 
    387     /** Task stack change listeners. */
    388     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
    389             new RemoteCallbackList<ITaskStackListener>();
    390 
    391     public IntentFirewall mIntentFirewall;
    392 
    393     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    394     // default actuion automatically.  Important for devices without direct input
    395     // devices.
    396     private boolean mShowDialogs = true;
    397 
    398     BroadcastQueue mFgBroadcastQueue;
    399     BroadcastQueue mBgBroadcastQueue;
    400     // Convenient for easy iteration over the queues. Foreground is first
    401     // so that dispatch of foreground broadcasts gets precedence.
    402     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    403 
    404     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    405         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    406         if (DEBUG_BACKGROUND_BROADCAST) {
    407             Slog.i(TAG, "Broadcast intent " + intent + " on "
    408                     + (isFg ? "foreground" : "background")
    409                     + " queue");
    410         }
    411         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    412     }
    413 
    414     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    415         for (BroadcastQueue queue : mBroadcastQueues) {
    416             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    417             if (r != null) {
    418                 return r;
    419             }
    420         }
    421         return null;
    422     }
    423 
    424     /**
    425      * Activity we have told the window manager to have key focus.
    426      */
    427     ActivityRecord mFocusedActivity = null;
    428 
    429     /**
    430      * List of intents that were used to start the most recent tasks.
    431      */
    432     ArrayList<TaskRecord> mRecentTasks;
    433     ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
    434 
    435     /**
    436      * For addAppTask: cached of the last activity component that was added.
    437      */
    438     ComponentName mLastAddedTaskComponent;
    439 
    440     /**
    441      * For addAppTask: cached of the last activity uid that was added.
    442      */
    443     int mLastAddedTaskUid;
    444 
    445     /**
    446      * For addAppTask: cached of the last ActivityInfo that was added.
    447      */
    448     ActivityInfo mLastAddedTaskActivity;
    449 
    450     public class PendingAssistExtras extends Binder implements Runnable {
    451         public final ActivityRecord activity;
    452         public final Bundle extras;
    453         public final Intent intent;
    454         public final String hint;
    455         public final int userHandle;
    456         public boolean haveResult = false;
    457         public Bundle result = null;
    458         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    459                 String _hint, int _userHandle) {
    460             activity = _activity;
    461             extras = _extras;
    462             intent = _intent;
    463             hint = _hint;
    464             userHandle = _userHandle;
    465         }
    466         @Override
    467         public void run() {
    468             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    469             synchronized (this) {
    470                 haveResult = true;
    471                 notifyAll();
    472             }
    473         }
    474     }
    475 
    476     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    477             = new ArrayList<PendingAssistExtras>();
    478 
    479     /**
    480      * Process management.
    481      */
    482     final ProcessList mProcessList = new ProcessList();
    483 
    484     /**
    485      * All of the applications we currently have running organized by name.
    486      * The keys are strings of the application package name (as
    487      * returned by the package manager), and the keys are ApplicationRecord
    488      * objects.
    489      */
    490     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    491 
    492     /**
    493      * Tracking long-term execution of processes to look for abuse and other
    494      * bad app behavior.
    495      */
    496     final ProcessStatsService mProcessStats;
    497 
    498     /**
    499      * The currently running isolated processes.
    500      */
    501     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    502 
    503     /**
    504      * Counter for assigning isolated process uids, to avoid frequently reusing the
    505      * same ones.
    506      */
    507     int mNextIsolatedProcessUid = 0;
    508 
    509     /**
    510      * The currently running heavy-weight process, if any.
    511      */
    512     ProcessRecord mHeavyWeightProcess = null;
    513 
    514     /**
    515      * The last time that various processes have crashed.
    516      */
    517     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    518 
    519     /**
    520      * Information about a process that is currently marked as bad.
    521      */
    522     static final class BadProcessInfo {
    523         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
    524             this.time = time;
    525             this.shortMsg = shortMsg;
    526             this.longMsg = longMsg;
    527             this.stack = stack;
    528         }
    529 
    530         final long time;
    531         final String shortMsg;
    532         final String longMsg;
    533         final String stack;
    534     }
    535 
    536     /**
    537      * Set of applications that we consider to be bad, and will reject
    538      * incoming broadcasts from (which the user has no control over).
    539      * Processes are added to this set when they have crashed twice within
    540      * a minimum amount of time; they are removed from it when they are
    541      * later restarted (hopefully due to some user action).  The value is the
    542      * time it was added to the list.
    543      */
    544     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
    545 
    546     /**
    547      * All of the processes we currently have running organized by pid.
    548      * The keys are the pid running the application.
    549      *
    550      * <p>NOTE: This object is protected by its own lock, NOT the global
    551      * activity manager lock!
    552      */
    553     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    554 
    555     /**
    556      * All of the processes that have been forced to be foreground.  The key
    557      * is the pid of the caller who requested it (we hold a death
    558      * link on it).
    559      */
    560     abstract class ForegroundToken implements IBinder.DeathRecipient {
    561         int pid;
    562         IBinder token;
    563     }
    564     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    565 
    566     /**
    567      * List of records for processes that someone had tried to start before the
    568      * system was ready.  We don't start them at that point, but ensure they
    569      * are started by the time booting is complete.
    570      */
    571     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    572 
    573     /**
    574      * List of persistent applications that are in the process
    575      * of being started.
    576      */
    577     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    578 
    579     /**
    580      * Processes that are being forcibly torn down.
    581      */
    582     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    583 
    584     /**
    585      * List of running applications, sorted by recent usage.
    586      * The first entry in the list is the least recently used.
    587      */
    588     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    589 
    590     /**
    591      * Where in mLruProcesses that the processes hosting activities start.
    592      */
    593     int mLruProcessActivityStart = 0;
    594 
    595     /**
    596      * Where in mLruProcesses that the processes hosting services start.
    597      * This is after (lower index) than mLruProcessesActivityStart.
    598      */
    599     int mLruProcessServiceStart = 0;
    600 
    601     /**
    602      * List of processes that should gc as soon as things are idle.
    603      */
    604     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    605 
    606     /**
    607      * Processes we want to collect PSS data from.
    608      */
    609     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    610 
    611     /**
    612      * Last time we requested PSS data of all processes.
    613      */
    614     long mLastFullPssTime = SystemClock.uptimeMillis();
    615 
    616     /**
    617      * If set, the next time we collect PSS data we should do a full collection
    618      * with data from native processes and the kernel.
    619      */
    620     boolean mFullPssPending = false;
    621 
    622     /**
    623      * This is the process holding what we currently consider to be
    624      * the "home" activity.
    625      */
    626     ProcessRecord mHomeProcess;
    627 
    628     /**
    629      * This is the process holding the activity the user last visited that
    630      * is in a different process from the one they are currently in.
    631      */
    632     ProcessRecord mPreviousProcess;
    633 
    634     /**
    635      * The time at which the previous process was last visible.
    636      */
    637     long mPreviousProcessVisibleTime;
    638 
    639     /**
    640      * Which uses have been started, so are allowed to run code.
    641      */
    642     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    643 
    644     /**
    645      * LRU list of history of current users.  Most recently current is at the end.
    646      */
    647     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    648 
    649     /**
    650      * Constant array of the users that are currently started.
    651      */
    652     int[] mStartedUserArray = new int[] { 0 };
    653 
    654     /**
    655      * Registered observers of the user switching mechanics.
    656      */
    657     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    658             = new RemoteCallbackList<IUserSwitchObserver>();
    659 
    660     /**
    661      * Currently active user switch.
    662      */
    663     Object mCurUserSwitchCallback;
    664 
    665     /**
    666      * Packages that the user has asked to have run in screen size
    667      * compatibility mode instead of filling the screen.
    668      */
    669     final CompatModePackages mCompatModePackages;
    670 
    671     /**
    672      * Set of IntentSenderRecord objects that are currently active.
    673      */
    674     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    675             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    676 
    677     /**
    678      * Fingerprints (hashCode()) of stack traces that we've
    679      * already logged DropBox entries for.  Guarded by itself.  If
    680      * something (rogue user app) forces this over
    681      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    682      */
    683     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    684     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    685 
    686     /**
    687      * Strict Mode background batched logging state.
    688      *
    689      * The string buffer is guarded by itself, and its lock is also
    690      * used to determine if another batched write is already
    691      * in-flight.
    692      */
    693     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    694 
    695     /**
    696      * Keeps track of all IIntentReceivers that have been registered for
    697      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    698      * a ReceiverList.
    699      */
    700     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
    701             new HashMap<IBinder, ReceiverList>();
    702 
    703     /**
    704      * Resolver for broadcast intents to registered receivers.
    705      * Holds BroadcastFilter (subclass of IntentFilter).
    706      */
    707     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    708             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    709         @Override
    710         protected boolean allowFilterResult(
    711                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    712             IBinder target = filter.receiverList.receiver.asBinder();
    713             for (int i=dest.size()-1; i>=0; i--) {
    714                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    715                     return false;
    716                 }
    717             }
    718             return true;
    719         }
    720 
    721         @Override
    722         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    723             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    724                     || userId == filter.owningUserId) {
    725                 return super.newResult(filter, match, userId);
    726             }
    727             return null;
    728         }
    729 
    730         @Override
    731         protected BroadcastFilter[] newArray(int size) {
    732             return new BroadcastFilter[size];
    733         }
    734 
    735         @Override
    736         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    737             return packageName.equals(filter.packageName);
    738         }
    739     };
    740 
    741     /**
    742      * State of all active sticky broadcasts per user.  Keys are the action of the
    743      * sticky Intent, values are an ArrayList of all broadcasted intents with
    744      * that action (which should usually be one).  The SparseArray is keyed
    745      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    746      * for stickies that are sent to all users.
    747      */
    748     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    749             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    750 
    751     final ActiveServices mServices;
    752 
    753     final static class Association {
    754         final int mSourceUid;
    755         final String mSourceProcess;
    756         final int mTargetUid;
    757         final ComponentName mTargetComponent;
    758         final String mTargetProcess;
    759 
    760         int mCount;
    761         long mTime;
    762 
    763         int mNesting;
    764         long mStartTime;
    765 
    766         Association(int sourceUid, String sourceProcess, int targetUid,
    767                 ComponentName targetComponent, String targetProcess) {
    768             mSourceUid = sourceUid;
    769             mSourceProcess = sourceProcess;
    770             mTargetUid = targetUid;
    771             mTargetComponent = targetComponent;
    772             mTargetProcess = targetProcess;
    773         }
    774     }
    775 
    776     /**
    777      * When service association tracking is enabled, this is all of the associations we
    778      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
    779      * -> association data.
    780      */
    781     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
    782             mAssociations = new SparseArray<>();
    783     boolean mTrackingAssociations;
    784 
    785     /**
    786      * Backup/restore process management
    787      */
    788     String mBackupAppName = null;
    789     BackupRecord mBackupTarget = null;
    790 
    791     final ProviderMap mProviderMap;
    792 
    793     /**
    794      * List of content providers who have clients waiting for them.  The
    795      * application is currently being launched and the provider will be
    796      * removed from this list once it is published.
    797      */
    798     final ArrayList<ContentProviderRecord> mLaunchingProviders
    799             = new ArrayList<ContentProviderRecord>();
    800 
    801     /**
    802      * File storing persisted {@link #mGrantedUriPermissions}.
    803      */
    804     private final AtomicFile mGrantFile;
    805 
    806     /** XML constants used in {@link #mGrantFile} */
    807     private static final String TAG_URI_GRANTS = "uri-grants";
    808     private static final String TAG_URI_GRANT = "uri-grant";
    809     private static final String ATTR_USER_HANDLE = "userHandle";
    810     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
    811     private static final String ATTR_TARGET_USER_ID = "targetUserId";
    812     private static final String ATTR_SOURCE_PKG = "sourcePkg";
    813     private static final String ATTR_TARGET_PKG = "targetPkg";
    814     private static final String ATTR_URI = "uri";
    815     private static final String ATTR_MODE_FLAGS = "modeFlags";
    816     private static final String ATTR_CREATED_TIME = "createdTime";
    817     private static final String ATTR_PREFIX = "prefix";
    818 
    819     /**
    820      * Global set of specific {@link Uri} permissions that have been granted.
    821      * This optimized lookup structure maps from {@link UriPermission#targetUid}
    822      * to {@link UriPermission#uri} to {@link UriPermission}.
    823      */
    824     @GuardedBy("this")
    825     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
    826             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
    827 
    828     public static class GrantUri {
    829         public final int sourceUserId;
    830         public final Uri uri;
    831         public boolean prefix;
    832 
    833         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
    834             this.sourceUserId = sourceUserId;
    835             this.uri = uri;
    836             this.prefix = prefix;
    837         }
    838 
    839         @Override
    840         public int hashCode() {
    841             int hashCode = 1;
    842             hashCode = 31 * hashCode + sourceUserId;
    843             hashCode = 31 * hashCode + uri.hashCode();
    844             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
    845             return hashCode;
    846         }
    847 
    848         @Override
    849         public boolean equals(Object o) {
    850             if (o instanceof GrantUri) {
    851                 GrantUri other = (GrantUri) o;
    852                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
    853                         && prefix == other.prefix;
    854             }
    855             return false;
    856         }
    857 
    858         @Override
    859         public String toString() {
    860             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
    861             if (prefix) result += " [prefix]";
    862             return result;
    863         }
    864 
    865         public String toSafeString() {
    866             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
    867             if (prefix) result += " [prefix]";
    868             return result;
    869         }
    870 
    871         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
    872             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
    873                     ContentProvider.getUriWithoutUserId(uri), false);
    874         }
    875     }
    876 
    877     CoreSettingsObserver mCoreSettingsObserver;
    878 
    879     /**
    880      * Thread-local storage used to carry caller permissions over through
    881      * indirect content-provider access.
    882      */
    883     private class Identity {
    884         public final IBinder token;
    885         public final int pid;
    886         public final int uid;
    887 
    888         Identity(IBinder _token, int _pid, int _uid) {
    889             token = _token;
    890             pid = _pid;
    891             uid = _uid;
    892         }
    893     }
    894 
    895     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    896 
    897     /**
    898      * All information we have collected about the runtime performance of
    899      * any user id that can impact battery performance.
    900      */
    901     final BatteryStatsService mBatteryStatsService;
    902 
    903     /**
    904      * Information about component usage
    905      */
    906     UsageStatsManagerInternal mUsageStatsService;
    907 
    908     /**
    909      * Information about and control over application operations
    910      */
    911     final AppOpsService mAppOpsService;
    912 
    913     /**
    914      * Save recent tasks information across reboots.
    915      */
    916     final TaskPersister mTaskPersister;
    917 
    918     /**
    919      * Current configuration information.  HistoryRecord objects are given
    920      * a reference to this object to indicate which configuration they are
    921      * currently running in, so this object must be kept immutable.
    922      */
    923     Configuration mConfiguration = new Configuration();
    924 
    925     /**
    926      * Current sequencing integer of the configuration, for skipping old
    927      * configurations.
    928      */
    929     int mConfigurationSeq = 0;
    930 
    931     /**
    932      * Hardware-reported OpenGLES version.
    933      */
    934     final int GL_ES_VERSION;
    935 
    936     /**
    937      * List of initialization arguments to pass to all processes when binding applications to them.
    938      * For example, references to the commonly used services.
    939      */
    940     HashMap<String, IBinder> mAppBindArgs;
    941 
    942     /**
    943      * Temporary to avoid allocations.  Protected by main lock.
    944      */
    945     final StringBuilder mStringBuilder = new StringBuilder(256);
    946 
    947     /**
    948      * Used to control how we initialize the service.
    949      */
    950     ComponentName mTopComponent;
    951     String mTopAction = Intent.ACTION_MAIN;
    952     String mTopData;
    953     boolean mProcessesReady = false;
    954     boolean mSystemReady = false;
    955     boolean mBooting = false;
    956     boolean mCallFinishBooting = false;
    957     boolean mBootAnimationComplete = false;
    958     boolean mWaitingUpdate = false;
    959     boolean mDidUpdate = false;
    960     boolean mOnBattery = false;
    961     boolean mLaunchWarningShown = false;
    962 
    963     Context mContext;
    964 
    965     int mFactoryTest;
    966 
    967     boolean mCheckedForSetup;
    968 
    969     /**
    970      * The time at which we will allow normal application switches again,
    971      * after a call to {@link #stopAppSwitches()}.
    972      */
    973     long mAppSwitchesAllowedTime;
    974 
    975     /**
    976      * This is set to true after the first switch after mAppSwitchesAllowedTime
    977      * is set; any switches after that will clear the time.
    978      */
    979     boolean mDidAppSwitch;
    980 
    981     /**
    982      * Last time (in realtime) at which we checked for power usage.
    983      */
    984     long mLastPowerCheckRealtime;
    985 
    986     /**
    987      * Last time (in uptime) at which we checked for power usage.
    988      */
    989     long mLastPowerCheckUptime;
    990 
    991     /**
    992      * Set while we are wanting to sleep, to prevent any
    993      * activities from being started/resumed.
    994      */
    995     private boolean mSleeping = false;
    996 
    997     /**
    998      * Set while we are running a voice interaction.  This overrides
    999      * sleeping while it is active.
   1000      */
   1001     private boolean mRunningVoice = false;
   1002 
   1003     /**
   1004      * State of external calls telling us if the device is awake or asleep.
   1005      */
   1006     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
   1007 
   1008     static final int LOCK_SCREEN_HIDDEN = 0;
   1009     static final int LOCK_SCREEN_LEAVING = 1;
   1010     static final int LOCK_SCREEN_SHOWN = 2;
   1011     /**
   1012      * State of external call telling us if the lock screen is shown.
   1013      */
   1014     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
   1015 
   1016     /**
   1017      * Set if we are shutting down the system, similar to sleeping.
   1018      */
   1019     boolean mShuttingDown = false;
   1020 
   1021     /**
   1022      * Current sequence id for oom_adj computation traversal.
   1023      */
   1024     int mAdjSeq = 0;
   1025 
   1026     /**
   1027      * Current sequence id for process LRU updating.
   1028      */
   1029     int mLruSeq = 0;
   1030 
   1031     /**
   1032      * Keep track of the non-cached/empty process we last found, to help
   1033      * determine how to distribute cached/empty processes next time.
   1034      */
   1035     int mNumNonCachedProcs = 0;
   1036 
   1037     /**
   1038      * Keep track of the number of cached hidden procs, to balance oom adj
   1039      * distribution between those and empty procs.
   1040      */
   1041     int mNumCachedHiddenProcs = 0;
   1042 
   1043     /**
   1044      * Keep track of the number of service processes we last found, to
   1045      * determine on the next iteration which should be B services.
   1046      */
   1047     int mNumServiceProcs = 0;
   1048     int mNewNumAServiceProcs = 0;
   1049     int mNewNumServiceProcs = 0;
   1050 
   1051     /**
   1052      * Allow the current computed overall memory level of the system to go down?
   1053      * This is set to false when we are killing processes for reasons other than
   1054      * memory management, so that the now smaller process list will not be taken as
   1055      * an indication that memory is tighter.
   1056      */
   1057     boolean mAllowLowerMemLevel = false;
   1058 
   1059     /**
   1060      * The last computed memory level, for holding when we are in a state that
   1061      * processes are going away for other reasons.
   1062      */
   1063     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1064 
   1065     /**
   1066      * The last total number of process we have, to determine if changes actually look
   1067      * like a shrinking number of process due to lower RAM.
   1068      */
   1069     int mLastNumProcesses;
   1070 
   1071     /**
   1072      * The uptime of the last time we performed idle maintenance.
   1073      */
   1074     long mLastIdleTime = SystemClock.uptimeMillis();
   1075 
   1076     /**
   1077      * Total time spent with RAM that has been added in the past since the last idle time.
   1078      */
   1079     long mLowRamTimeSinceLastIdle = 0;
   1080 
   1081     /**
   1082      * If RAM is currently low, when that horrible situation started.
   1083      */
   1084     long mLowRamStartTime = 0;
   1085 
   1086     /**
   1087      * For reporting to battery stats the current top application.
   1088      */
   1089     private String mCurResumedPackage = null;
   1090     private int mCurResumedUid = -1;
   1091 
   1092     /**
   1093      * For reporting to battery stats the apps currently running foreground
   1094      * service.  The ProcessMap is package/uid tuples; each of these contain
   1095      * an array of the currently foreground processes.
   1096      */
   1097     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1098             = new ProcessMap<ArrayList<ProcessRecord>>();
   1099 
   1100     /**
   1101      * This is set if we had to do a delayed dexopt of an app before launching
   1102      * it, to increase the ANR timeouts in that case.
   1103      */
   1104     boolean mDidDexOpt;
   1105 
   1106     /**
   1107      * Set if the systemServer made a call to enterSafeMode.
   1108      */
   1109     boolean mSafeMode;
   1110 
   1111     /**
   1112      * If true, we are running under a test environment so will sample PSS from processes
   1113      * much more rapidly to try to collect better data when the tests are rapidly
   1114      * running through apps.
   1115      */
   1116     boolean mTestPssMode = false;
   1117 
   1118     String mDebugApp = null;
   1119     boolean mWaitForDebugger = false;
   1120     boolean mDebugTransient = false;
   1121     String mOrigDebugApp = null;
   1122     boolean mOrigWaitForDebugger = false;
   1123     boolean mAlwaysFinishActivities = false;
   1124     IActivityController mController = null;
   1125     String mProfileApp = null;
   1126     ProcessRecord mProfileProc = null;
   1127     String mProfileFile;
   1128     ParcelFileDescriptor mProfileFd;
   1129     int mSamplingInterval = 0;
   1130     boolean mAutoStopProfiler = false;
   1131     int mProfileType = 0;
   1132     String mOpenGlTraceApp = null;
   1133 
   1134     final long[] mTmpLong = new long[1];
   1135 
   1136     static class ProcessChangeItem {
   1137         static final int CHANGE_ACTIVITIES = 1<<0;
   1138         static final int CHANGE_PROCESS_STATE = 1<<1;
   1139         int changes;
   1140         int uid;
   1141         int pid;
   1142         int processState;
   1143         boolean foregroundActivities;
   1144     }
   1145 
   1146     final RemoteCallbackList<IProcessObserver> mProcessObservers
   1147             = new RemoteCallbackList<IProcessObserver>();
   1148     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1149 
   1150     final ArrayList<ProcessChangeItem> mPendingProcessChanges
   1151             = new ArrayList<ProcessChangeItem>();
   1152     final ArrayList<ProcessChangeItem> mAvailProcessChanges
   1153             = new ArrayList<ProcessChangeItem>();
   1154 
   1155     /**
   1156      * Runtime CPU use collection thread.  This object's lock is used to
   1157      * perform synchronization with the thread (notifying it to run).
   1158      */
   1159     final Thread mProcessCpuThread;
   1160 
   1161     /**
   1162      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1163      * Must acquire this object's lock when accessing it.
   1164      * NOTE: this lock will be held while doing long operations (trawling
   1165      * through all processes in /proc), so it should never be acquired by
   1166      * any critical paths such as when holding the main activity manager lock.
   1167      */
   1168     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1169             MONITOR_THREAD_CPU_USAGE);
   1170     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1171     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1172 
   1173     long mLastWriteTime = 0;
   1174 
   1175     /**
   1176      * Used to retain an update lock when the foreground activity is in
   1177      * immersive mode.
   1178      */
   1179     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1180 
   1181     /**
   1182      * Set to true after the system has finished booting.
   1183      */
   1184     boolean mBooted = false;
   1185 
   1186     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
   1187     int mProcessLimitOverride = -1;
   1188 
   1189     WindowManagerService mWindowManager;
   1190 
   1191     final ActivityThread mSystemThread;
   1192 
   1193     // Holds the current foreground user's id
   1194     int mCurrentUserId = 0;
   1195     // Holds the target user's id during a user switch
   1196     int mTargetUserId = UserHandle.USER_NULL;
   1197     // If there are multiple profiles for the current user, their ids are here
   1198     // Currently only the primary user can have managed profiles
   1199     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
   1200 
   1201     /**
   1202      * Mapping from each known user ID to the profile group ID it is associated with.
   1203      */
   1204     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
   1205 
   1206     private UserManagerService mUserManager;
   1207 
   1208     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1209         final ProcessRecord mApp;
   1210         final int mPid;
   1211         final IApplicationThread mAppThread;
   1212 
   1213         AppDeathRecipient(ProcessRecord app, int pid,
   1214                 IApplicationThread thread) {
   1215             if (localLOGV) Slog.v(
   1216                 TAG, "New death recipient " + this
   1217                 + " for thread " + thread.asBinder());
   1218             mApp = app;
   1219             mPid = pid;
   1220             mAppThread = thread;
   1221         }
   1222 
   1223         @Override
   1224         public void binderDied() {
   1225             if (localLOGV) Slog.v(
   1226                 TAG, "Death received in " + this
   1227                 + " for thread " + mAppThread.asBinder());
   1228             synchronized(ActivityManagerService.this) {
   1229                 appDiedLocked(mApp, mPid, mAppThread);
   1230             }
   1231         }
   1232     }
   1233 
   1234     static final int SHOW_ERROR_MSG = 1;
   1235     static final int SHOW_NOT_RESPONDING_MSG = 2;
   1236     static final int SHOW_FACTORY_ERROR_MSG = 3;
   1237     static final int UPDATE_CONFIGURATION_MSG = 4;
   1238     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1239     static final int WAIT_FOR_DEBUGGER_MSG = 6;
   1240     static final int SERVICE_TIMEOUT_MSG = 12;
   1241     static final int UPDATE_TIME_ZONE = 13;
   1242     static final int SHOW_UID_ERROR_MSG = 14;
   1243     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
   1244     static final int PROC_START_TIMEOUT_MSG = 20;
   1245     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1246     static final int KILL_APPLICATION_MSG = 22;
   1247     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1248     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1249     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1250     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
   1251     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1252     static final int CLEAR_DNS_CACHE_MSG = 28;
   1253     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1254     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
   1255     static final int DISPATCH_PROCESSES_CHANGED = 31;
   1256     static final int DISPATCH_PROCESS_DIED = 32;
   1257     static final int REPORT_MEM_USAGE_MSG = 33;
   1258     static final int REPORT_USER_SWITCH_MSG = 34;
   1259     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1260     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1261     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1262     static final int PERSIST_URI_GRANTS_MSG = 38;
   1263     static final int REQUEST_ALL_PSS_MSG = 39;
   1264     static final int START_PROFILES_MSG = 40;
   1265     static final int UPDATE_TIME = 41;
   1266     static final int SYSTEM_USER_START_MSG = 42;
   1267     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1268     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1269     static final int FINISH_BOOTING_MSG = 45;
   1270     static final int START_USER_SWITCH_MSG = 46;
   1271     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1272     static final int DISMISS_DIALOG_MSG = 48;
   1273     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
   1274 
   1275     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1276     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1277     static final int FIRST_COMPAT_MODE_MSG = 300;
   1278     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1279 
   1280     CompatModeDialog mCompatModeDialog;
   1281     long mLastMemUsageReportTime = 0;
   1282 
   1283     /**
   1284      * Flag whether the current user is a "monkey", i.e. whether
   1285      * the UI is driven by a UI automation tool.
   1286      */
   1287     private boolean mUserIsMonkey;
   1288 
   1289     /** Flag whether the device has a Recents UI */
   1290     boolean mHasRecents;
   1291 
   1292     /** The dimensions of the thumbnails in the Recents UI. */
   1293     int mThumbnailWidth;
   1294     int mThumbnailHeight;
   1295 
   1296     final ServiceThread mHandlerThread;
   1297     final MainHandler mHandler;
   1298 
   1299     final class MainHandler extends Handler {
   1300         public MainHandler(Looper looper) {
   1301             super(looper, null, true);
   1302         }
   1303 
   1304         @Override
   1305         public void handleMessage(Message msg) {
   1306             switch (msg.what) {
   1307             case SHOW_ERROR_MSG: {
   1308                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1309                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   1310                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   1311                 synchronized (ActivityManagerService.this) {
   1312                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1313                     AppErrorResult res = (AppErrorResult) data.get("result");
   1314                     if (proc != null && proc.crashDialog != null) {
   1315                         Slog.e(TAG, "App already has crash dialog: " + proc);
   1316                         if (res != null) {
   1317                             res.set(0);
   1318                         }
   1319                         return;
   1320                     }
   1321                     boolean isBackground = (UserHandle.getAppId(proc.uid)
   1322                             >= Process.FIRST_APPLICATION_UID
   1323                             && proc.pid != MY_PID);
   1324                     for (int userId : mCurrentProfileIds) {
   1325                         isBackground &= (proc.userId != userId);
   1326                     }
   1327                     if (isBackground && !showBackground) {
   1328                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
   1329                         if (res != null) {
   1330                             res.set(0);
   1331                         }
   1332                         return;
   1333                     }
   1334                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1335                         Dialog d = new AppErrorDialog(mContext,
   1336                                 ActivityManagerService.this, res, proc);
   1337                         d.show();
   1338                         proc.crashDialog = d;
   1339                     } else {
   1340                         // The device is asleep, so just pretend that the user
   1341                         // saw a crash dialog and hit "force quit".
   1342                         if (res != null) {
   1343                             res.set(0);
   1344                         }
   1345                     }
   1346                 }
   1347 
   1348                 ensureBootCompleted();
   1349             } break;
   1350             case SHOW_NOT_RESPONDING_MSG: {
   1351                 synchronized (ActivityManagerService.this) {
   1352                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1353                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1354                     if (proc != null && proc.anrDialog != null) {
   1355                         Slog.e(TAG, "App already has anr dialog: " + proc);
   1356                         return;
   1357                     }
   1358 
   1359                     Intent intent = new Intent("android.intent.action.ANR");
   1360                     if (!mProcessesReady) {
   1361                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   1362                                 | Intent.FLAG_RECEIVER_FOREGROUND);
   1363                     }
   1364                     broadcastIntentLocked(null, null, intent,
   1365                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   1366                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   1367 
   1368                     if (mShowDialogs) {
   1369                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1370                                 mContext, proc, (ActivityRecord)data.get("activity"),
   1371                                 msg.arg1 != 0);
   1372                         d.show();
   1373                         proc.anrDialog = d;
   1374                     } else {
   1375                         // Just kill the app if there is no dialog to be shown.
   1376                         killAppAtUsersRequest(proc, null);
   1377                     }
   1378                 }
   1379 
   1380                 ensureBootCompleted();
   1381             } break;
   1382             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1383                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1384                 synchronized (ActivityManagerService.this) {
   1385                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1386                     if (proc == null) {
   1387                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1388                         break;
   1389                     }
   1390                     if (proc.crashDialog != null) {
   1391                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1392                         return;
   1393                     }
   1394                     AppErrorResult res = (AppErrorResult) data.get("result");
   1395                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1396                         Dialog d = new StrictModeViolationDialog(mContext,
   1397                                 ActivityManagerService.this, res, proc);
   1398                         d.show();
   1399                         proc.crashDialog = d;
   1400                     } else {
   1401                         // The device is asleep, so just pretend that the user
   1402                         // saw a crash dialog and hit "force quit".
   1403                         res.set(0);
   1404                     }
   1405                 }
   1406                 ensureBootCompleted();
   1407             } break;
   1408             case SHOW_FACTORY_ERROR_MSG: {
   1409                 Dialog d = new FactoryErrorDialog(
   1410                     mContext, msg.getData().getCharSequence("msg"));
   1411                 d.show();
   1412                 ensureBootCompleted();
   1413             } break;
   1414             case UPDATE_CONFIGURATION_MSG: {
   1415                 final ContentResolver resolver = mContext.getContentResolver();
   1416                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1417             } break;
   1418             case GC_BACKGROUND_PROCESSES_MSG: {
   1419                 synchronized (ActivityManagerService.this) {
   1420                     performAppGcsIfAppropriateLocked();
   1421                 }
   1422             } break;
   1423             case WAIT_FOR_DEBUGGER_MSG: {
   1424                 synchronized (ActivityManagerService.this) {
   1425                     ProcessRecord app = (ProcessRecord)msg.obj;
   1426                     if (msg.arg1 != 0) {
   1427                         if (!app.waitedForDebugger) {
   1428                             Dialog d = new AppWaitingForDebuggerDialog(
   1429                                     ActivityManagerService.this,
   1430                                     mContext, app);
   1431                             app.waitDialog = d;
   1432                             app.waitedForDebugger = true;
   1433                             d.show();
   1434                         }
   1435                     } else {
   1436                         if (app.waitDialog != null) {
   1437                             app.waitDialog.dismiss();
   1438                             app.waitDialog = null;
   1439                         }
   1440                     }
   1441                 }
   1442             } break;
   1443             case SERVICE_TIMEOUT_MSG: {
   1444                 if (mDidDexOpt) {
   1445                     mDidDexOpt = false;
   1446                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1447                     nmsg.obj = msg.obj;
   1448                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1449                     return;
   1450                 }
   1451                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1452             } break;
   1453             case UPDATE_TIME_ZONE: {
   1454                 synchronized (ActivityManagerService.this) {
   1455                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1456                         ProcessRecord r = mLruProcesses.get(i);
   1457                         if (r.thread != null) {
   1458                             try {
   1459                                 r.thread.updateTimeZone();
   1460                             } catch (RemoteException ex) {
   1461                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1462                             }
   1463                         }
   1464                     }
   1465                 }
   1466             } break;
   1467             case CLEAR_DNS_CACHE_MSG: {
   1468                 synchronized (ActivityManagerService.this) {
   1469                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1470                         ProcessRecord r = mLruProcesses.get(i);
   1471                         if (r.thread != null) {
   1472                             try {
   1473                                 r.thread.clearDnsCache();
   1474                             } catch (RemoteException ex) {
   1475                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1476                             }
   1477                         }
   1478                     }
   1479                 }
   1480             } break;
   1481             case UPDATE_HTTP_PROXY_MSG: {
   1482                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   1483                 String host = "";
   1484                 String port = "";
   1485                 String exclList = "";
   1486                 Uri pacFileUrl = Uri.EMPTY;
   1487                 if (proxy != null) {
   1488                     host = proxy.getHost();
   1489                     port = Integer.toString(proxy.getPort());
   1490                     exclList = proxy.getExclusionListAsString();
   1491                     pacFileUrl = proxy.getPacFileUrl();
   1492                 }
   1493                 synchronized (ActivityManagerService.this) {
   1494                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1495                         ProcessRecord r = mLruProcesses.get(i);
   1496                         if (r.thread != null) {
   1497                             try {
   1498                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1499                             } catch (RemoteException ex) {
   1500                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1501                                         r.info.processName);
   1502                             }
   1503                         }
   1504                     }
   1505                 }
   1506             } break;
   1507             case SHOW_UID_ERROR_MSG: {
   1508                 if (mShowDialogs) {
   1509                     AlertDialog d = new BaseErrorDialog(mContext);
   1510                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1511                     d.setCancelable(false);
   1512                     d.setTitle(mContext.getText(R.string.android_system_label));
   1513                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
   1514                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1515                             mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
   1516                     d.show();
   1517                 }
   1518             } break;
   1519             case SHOW_FINGERPRINT_ERROR_MSG: {
   1520                 if (mShowDialogs) {
   1521                     AlertDialog d = new BaseErrorDialog(mContext);
   1522                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1523                     d.setCancelable(false);
   1524                     d.setTitle(mContext.getText(R.string.android_system_label));
   1525                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
   1526                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
   1527                             mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
   1528                     d.show();
   1529                 }
   1530             } break;
   1531             case PROC_START_TIMEOUT_MSG: {
   1532                 if (mDidDexOpt) {
   1533                     mDidDexOpt = false;
   1534                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1535                     nmsg.obj = msg.obj;
   1536                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1537                     return;
   1538                 }
   1539                 ProcessRecord app = (ProcessRecord)msg.obj;
   1540                 synchronized (ActivityManagerService.this) {
   1541                     processStartTimedOutLocked(app);
   1542                 }
   1543             } break;
   1544             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1545                 synchronized (ActivityManagerService.this) {
   1546                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
   1547                 }
   1548             } break;
   1549             case KILL_APPLICATION_MSG: {
   1550                 synchronized (ActivityManagerService.this) {
   1551                     int appid = msg.arg1;
   1552                     boolean restart = (msg.arg2 == 1);
   1553                     Bundle bundle = (Bundle)msg.obj;
   1554                     String pkg = bundle.getString("pkg");
   1555                     String reason = bundle.getString("reason");
   1556                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1557                             false, UserHandle.USER_ALL, reason);
   1558                 }
   1559             } break;
   1560             case FINALIZE_PENDING_INTENT_MSG: {
   1561                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1562             } break;
   1563             case POST_HEAVY_NOTIFICATION_MSG: {
   1564                 INotificationManager inm = NotificationManager.getService();
   1565                 if (inm == null) {
   1566                     return;
   1567                 }
   1568 
   1569                 ActivityRecord root = (ActivityRecord)msg.obj;
   1570                 ProcessRecord process = root.app;
   1571                 if (process == null) {
   1572                     return;
   1573                 }
   1574 
   1575                 try {
   1576                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1577                     String text = mContext.getString(R.string.heavy_weight_notification,
   1578                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1579                     Notification notification = new Notification();
   1580                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1581                     notification.when = 0;
   1582                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1583                     notification.tickerText = text;
   1584                     notification.defaults = 0; // please be quiet
   1585                     notification.sound = null;
   1586                     notification.vibrate = null;
   1587                     notification.color = mContext.getResources().getColor(
   1588                             com.android.internal.R.color.system_notification_accent_color);
   1589                     notification.setLatestEventInfo(context, text,
   1590                             mContext.getText(R.string.heavy_weight_notification_detail),
   1591                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1592                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1593                                     new UserHandle(root.userId)));
   1594 
   1595                     try {
   1596                         int[] outId = new int[1];
   1597                         inm.enqueueNotificationWithTag("android", "android", null,
   1598                                 R.string.heavy_weight_notification,
   1599                                 notification, outId, root.userId);
   1600                     } catch (RuntimeException e) {
   1601                         Slog.w(ActivityManagerService.TAG,
   1602                                 "Error showing notification for heavy-weight app", e);
   1603                     } catch (RemoteException e) {
   1604                     }
   1605                 } catch (NameNotFoundException e) {
   1606                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1607                 }
   1608             } break;
   1609             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1610                 INotificationManager inm = NotificationManager.getService();
   1611                 if (inm == null) {
   1612                     return;
   1613                 }
   1614                 try {
   1615                     inm.cancelNotificationWithTag("android", null,
   1616                             R.string.heavy_weight_notification,  msg.arg1);
   1617                 } catch (RuntimeException e) {
   1618                     Slog.w(ActivityManagerService.TAG,
   1619                             "Error canceling notification for service", e);
   1620                 } catch (RemoteException e) {
   1621                 }
   1622             } break;
   1623             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1624                 synchronized (ActivityManagerService.this) {
   1625                     checkExcessivePowerUsageLocked(true);
   1626                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1627                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1628                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1629                 }
   1630             } break;
   1631             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1632                 synchronized (ActivityManagerService.this) {
   1633                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1634                     if (mCompatModeDialog != null) {
   1635                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1636                                 ar.info.applicationInfo.packageName)) {
   1637                             return;
   1638                         }
   1639                         mCompatModeDialog.dismiss();
   1640                         mCompatModeDialog = null;
   1641                     }
   1642                     if (ar != null && false) {
   1643                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1644                                 ar.packageName)) {
   1645                             int mode = mCompatModePackages.computeCompatModeLocked(
   1646                                     ar.info.applicationInfo);
   1647                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1648                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1649                                 mCompatModeDialog = new CompatModeDialog(
   1650                                         ActivityManagerService.this, mContext,
   1651                                         ar.info.applicationInfo);
   1652                                 mCompatModeDialog.show();
   1653                             }
   1654                         }
   1655                     }
   1656                 }
   1657                 break;
   1658             }
   1659             case DISPATCH_PROCESSES_CHANGED: {
   1660                 dispatchProcessesChanged();
   1661                 break;
   1662             }
   1663             case DISPATCH_PROCESS_DIED: {
   1664                 final int pid = msg.arg1;
   1665                 final int uid = msg.arg2;
   1666                 dispatchProcessDied(pid, uid);
   1667                 break;
   1668             }
   1669             case REPORT_MEM_USAGE_MSG: {
   1670                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1671                 Thread thread = new Thread() {
   1672                     @Override public void run() {
   1673                         reportMemUsage(memInfos);
   1674                     }
   1675                 };
   1676                 thread.start();
   1677                 break;
   1678             }
   1679             case START_USER_SWITCH_MSG: {
   1680                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
   1681                 break;
   1682             }
   1683             case REPORT_USER_SWITCH_MSG: {
   1684                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1685                 break;
   1686             }
   1687             case CONTINUE_USER_SWITCH_MSG: {
   1688                 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1689                 break;
   1690             }
   1691             case USER_SWITCH_TIMEOUT_MSG: {
   1692                 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1693                 break;
   1694             }
   1695             case IMMERSIVE_MODE_LOCK_MSG: {
   1696                 final boolean nextState = (msg.arg1 != 0);
   1697                 if (mUpdateLock.isHeld() != nextState) {
   1698                     if (DEBUG_IMMERSIVE) {
   1699                         final ActivityRecord r = (ActivityRecord) msg.obj;
   1700                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
   1701                     }
   1702                     if (nextState) {
   1703                         mUpdateLock.acquire();
   1704                     } else {
   1705                         mUpdateLock.release();
   1706                     }
   1707                 }
   1708                 break;
   1709             }
   1710             case PERSIST_URI_GRANTS_MSG: {
   1711                 writeGrantedUriPermissions();
   1712                 break;
   1713             }
   1714             case REQUEST_ALL_PSS_MSG: {
   1715                 synchronized (ActivityManagerService.this) {
   1716                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1717                 }
   1718                 break;
   1719             }
   1720             case START_PROFILES_MSG: {
   1721                 synchronized (ActivityManagerService.this) {
   1722                     startProfilesLocked();
   1723                 }
   1724                 break;
   1725             }
   1726             case UPDATE_TIME: {
   1727                 synchronized (ActivityManagerService.this) {
   1728                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1729                         ProcessRecord r = mLruProcesses.get(i);
   1730                         if (r.thread != null) {
   1731                             try {
   1732                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
   1733                             } catch (RemoteException ex) {
   1734                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
   1735                             }
   1736                         }
   1737                     }
   1738                 }
   1739                 break;
   1740             }
   1741             case SYSTEM_USER_START_MSG: {
   1742                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   1743                         Integer.toString(msg.arg1), msg.arg1);
   1744                 mSystemServiceManager.startUser(msg.arg1);
   1745                 break;
   1746             }
   1747             case SYSTEM_USER_CURRENT_MSG: {
   1748                 mBatteryStatsService.noteEvent(
   1749                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   1750                         Integer.toString(msg.arg2), msg.arg2);
   1751                 mBatteryStatsService.noteEvent(
   1752                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   1753                         Integer.toString(msg.arg1), msg.arg1);
   1754                 mSystemServiceManager.switchUser(msg.arg1);
   1755                 break;
   1756             }
   1757             case ENTER_ANIMATION_COMPLETE_MSG: {
   1758                 synchronized (ActivityManagerService.this) {
   1759                     ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
   1760                     if (r != null && r.app != null && r.app.thread != null) {
   1761                         try {
   1762                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   1763                         } catch (RemoteException e) {
   1764                         }
   1765                     }
   1766                 }
   1767                 break;
   1768             }
   1769             case FINISH_BOOTING_MSG: {
   1770                 if (msg.arg1 != 0) {
   1771                     finishBooting();
   1772                 }
   1773                 if (msg.arg2 != 0) {
   1774                     enableScreenAfterBoot();
   1775                 }
   1776                 break;
   1777             }
   1778             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   1779                 try {
   1780                     Locale l = (Locale) msg.obj;
   1781                     IBinder service = ServiceManager.getService("mount");
   1782                     IMountService mountService = IMountService.Stub.asInterface(service);
   1783                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   1784                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   1785                 } catch (RemoteException e) {
   1786                     Log.e(TAG, "Error storing locale for decryption UI", e);
   1787                 }
   1788                 break;
   1789             }
   1790             case DISMISS_DIALOG_MSG: {
   1791                 final Dialog d = (Dialog) msg.obj;
   1792                 d.dismiss();
   1793                 break;
   1794             }
   1795             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
   1796                 synchronized (ActivityManagerService.this) {
   1797                     int i = mTaskStackListeners.beginBroadcast();
   1798                     while (i > 0) {
   1799                         i--;
   1800                         try {
   1801                             // Make a one-way callback to the listener
   1802                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
   1803                         } catch (RemoteException e){
   1804                             // Handled by the RemoteCallbackList
   1805                         }
   1806                     }
   1807                     mTaskStackListeners.finishBroadcast();
   1808                 }
   1809                 break;
   1810             }
   1811             }
   1812         }
   1813     };
   1814 
   1815     static final int COLLECT_PSS_BG_MSG = 1;
   1816 
   1817     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   1818         @Override
   1819         public void handleMessage(Message msg) {
   1820             switch (msg.what) {
   1821             case COLLECT_PSS_BG_MSG: {
   1822                 long start = SystemClock.uptimeMillis();
   1823                 MemInfoReader memInfo = null;
   1824                 synchronized (ActivityManagerService.this) {
   1825                     if (mFullPssPending) {
   1826                         mFullPssPending = false;
   1827                         memInfo = new MemInfoReader();
   1828                     }
   1829                 }
   1830                 if (memInfo != null) {
   1831                     updateCpuStatsNow();
   1832                     long nativeTotalPss = 0;
   1833                     synchronized (mProcessCpuTracker) {
   1834                         final int N = mProcessCpuTracker.countStats();
   1835                         for (int j=0; j<N; j++) {
   1836                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
   1837                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
   1838                                 // This is definitely an application process; skip it.
   1839                                 continue;
   1840                             }
   1841                             synchronized (mPidsSelfLocked) {
   1842                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
   1843                                     // This is one of our own processes; skip it.
   1844                                     continue;
   1845                                 }
   1846                             }
   1847                             nativeTotalPss += Debug.getPss(st.pid, null, null);
   1848                         }
   1849                     }
   1850                     memInfo.readMemInfo();
   1851                     synchronized (ActivityManagerService.this) {
   1852                         if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
   1853                                 + (SystemClock.uptimeMillis()-start) + "ms");
   1854                         mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
   1855                                 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
   1856                                 memInfo.getKernelUsedSizeKb(), nativeTotalPss);
   1857                     }
   1858                 }
   1859 
   1860                 int num = 0;
   1861                 long[] tmp = new long[1];
   1862                 do {
   1863                     ProcessRecord proc;
   1864                     int procState;
   1865                     int pid;
   1866                     long lastPssTime;
   1867                     synchronized (ActivityManagerService.this) {
   1868                         if (mPendingPssProcesses.size() <= 0) {
   1869                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
   1870                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
   1871                             mPendingPssProcesses.clear();
   1872                             return;
   1873                         }
   1874                         proc = mPendingPssProcesses.remove(0);
   1875                         procState = proc.pssProcState;
   1876                         lastPssTime = proc.lastPssTime;
   1877                         if (proc.thread != null && procState == proc.setProcState
   1878                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
   1879                                         < SystemClock.uptimeMillis()) {
   1880                             pid = proc.pid;
   1881                         } else {
   1882                             proc = null;
   1883                             pid = 0;
   1884                         }
   1885                     }
   1886                     if (proc != null) {
   1887                         long pss = Debug.getPss(pid, tmp, null);
   1888                         synchronized (ActivityManagerService.this) {
   1889                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
   1890                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
   1891                                 num++;
   1892                                 recordPssSample(proc, procState, pss, tmp[0],
   1893                                         SystemClock.uptimeMillis());
   1894                             }
   1895                         }
   1896                     }
   1897                 } while (true);
   1898             }
   1899             }
   1900         }
   1901     };
   1902 
   1903     public void setSystemProcess() {
   1904         try {
   1905             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   1906             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   1907             ServiceManager.addService("meminfo", new MemBinder(this));
   1908             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   1909             ServiceManager.addService("dbinfo", new DbBinder(this));
   1910             if (MONITOR_CPU_USAGE) {
   1911                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   1912             }
   1913             ServiceManager.addService("permission", new PermissionController(this));
   1914 
   1915             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   1916                     "android", STOCK_PM_FLAGS);
   1917             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   1918 
   1919             synchronized (this) {
   1920                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   1921                 app.persistent = true;
   1922                 app.pid = MY_PID;
   1923                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1924                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   1925                 mProcessNames.put(app.processName, app.uid, app);
   1926                 synchronized (mPidsSelfLocked) {
   1927                     mPidsSelfLocked.put(app.pid, app);
   1928                 }
   1929                 updateLruProcessLocked(app, false, null);
   1930                 updateOomAdjLocked();
   1931             }
   1932         } catch (PackageManager.NameNotFoundException e) {
   1933             throw new RuntimeException(
   1934                     "Unable to find android system package", e);
   1935         }
   1936     }
   1937 
   1938     public void setWindowManager(WindowManagerService wm) {
   1939         mWindowManager = wm;
   1940         mStackSupervisor.setWindowManager(wm);
   1941     }
   1942 
   1943     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   1944         mUsageStatsService = usageStatsManager;
   1945     }
   1946 
   1947     public void startObservingNativeCrashes() {
   1948         final NativeCrashListener ncl = new NativeCrashListener(this);
   1949         ncl.start();
   1950     }
   1951 
   1952     public IAppOpsService getAppOpsService() {
   1953         return mAppOpsService;
   1954     }
   1955 
   1956     static class MemBinder extends Binder {
   1957         ActivityManagerService mActivityManagerService;
   1958         MemBinder(ActivityManagerService activityManagerService) {
   1959             mActivityManagerService = activityManagerService;
   1960         }
   1961 
   1962         @Override
   1963         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1964             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1965                     != PackageManager.PERMISSION_GRANTED) {
   1966                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1967                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1968                         + " without permission " + android.Manifest.permission.DUMP);
   1969                 return;
   1970             }
   1971 
   1972             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   1973         }
   1974     }
   1975 
   1976     static class GraphicsBinder extends Binder {
   1977         ActivityManagerService mActivityManagerService;
   1978         GraphicsBinder(ActivityManagerService activityManagerService) {
   1979             mActivityManagerService = activityManagerService;
   1980         }
   1981 
   1982         @Override
   1983         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1984             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1985                     != PackageManager.PERMISSION_GRANTED) {
   1986                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1987                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1988                         + " without permission " + android.Manifest.permission.DUMP);
   1989                 return;
   1990             }
   1991 
   1992             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1993         }
   1994     }
   1995 
   1996     static class DbBinder extends Binder {
   1997         ActivityManagerService mActivityManagerService;
   1998         DbBinder(ActivityManagerService activityManagerService) {
   1999             mActivityManagerService = activityManagerService;
   2000         }
   2001 
   2002         @Override
   2003         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2004             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2005                     != PackageManager.PERMISSION_GRANTED) {
   2006                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   2007                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2008                         + " without permission " + android.Manifest.permission.DUMP);
   2009                 return;
   2010             }
   2011 
   2012             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2013         }
   2014     }
   2015 
   2016     static class CpuBinder extends Binder {
   2017         ActivityManagerService mActivityManagerService;
   2018         CpuBinder(ActivityManagerService activityManagerService) {
   2019             mActivityManagerService = activityManagerService;
   2020         }
   2021 
   2022         @Override
   2023         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2024             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2025                     != PackageManager.PERMISSION_GRANTED) {
   2026                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   2027                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2028                         + " without permission " + android.Manifest.permission.DUMP);
   2029                 return;
   2030             }
   2031 
   2032             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2033                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2034                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2035                         SystemClock.uptimeMillis()));
   2036             }
   2037         }
   2038     }
   2039 
   2040     public static final class Lifecycle extends SystemService {
   2041         private final ActivityManagerService mService;
   2042 
   2043         public Lifecycle(Context context) {
   2044             super(context);
   2045             mService = new ActivityManagerService(context);
   2046         }
   2047 
   2048         @Override
   2049         public void onStart() {
   2050             mService.start();
   2051         }
   2052 
   2053         public ActivityManagerService getService() {
   2054             return mService;
   2055         }
   2056     }
   2057 
   2058     // Note: This method is invoked on the main thread but may need to attach various
   2059     // handlers to other threads.  So take care to be explicit about the looper.
   2060     public ActivityManagerService(Context systemContext) {
   2061         mContext = systemContext;
   2062         mFactoryTest = FactoryTest.getMode();
   2063         mSystemThread = ActivityThread.currentActivityThread();
   2064 
   2065         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2066 
   2067         mHandlerThread = new ServiceThread(TAG,
   2068                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2069         mHandlerThread.start();
   2070         mHandler = new MainHandler(mHandlerThread.getLooper());
   2071 
   2072         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2073                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2074         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2075                 "background", BROADCAST_BG_TIMEOUT, true);
   2076         mBroadcastQueues[0] = mFgBroadcastQueue;
   2077         mBroadcastQueues[1] = mBgBroadcastQueue;
   2078 
   2079         mServices = new ActiveServices(this);
   2080         mProviderMap = new ProviderMap(this);
   2081 
   2082         // TODO: Move creation of battery stats service outside of activity manager service.
   2083         File dataDir = Environment.getDataDirectory();
   2084         File systemDir = new File(dataDir, "system");
   2085         systemDir.mkdirs();
   2086         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2087         mBatteryStatsService.getActiveStatistics().readLocked();
   2088         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2089         mOnBattery = DEBUG_POWER ? true
   2090                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2091         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2092 
   2093         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2094 
   2095         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2096 
   2097         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2098 
   2099         // User 0 is the first and only user that runs at boot.
   2100         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   2101         mUserLru.add(Integer.valueOf(0));
   2102         updateStartedUserArrayLocked();
   2103 
   2104         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2105             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2106 
   2107         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
   2108 
   2109         mConfiguration.setToDefaults();
   2110         mConfiguration.locale = Locale.getDefault();
   2111 
   2112         mConfigurationSeq = mConfiguration.seq = 1;
   2113         mProcessCpuTracker.init();
   2114 
   2115         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2116         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2117         mStackSupervisor = new ActivityStackSupervisor(this);
   2118         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
   2119 
   2120         mProcessCpuThread = new Thread("CpuTracker") {
   2121             @Override
   2122             public void run() {
   2123                 while (true) {
   2124                     try {
   2125                         try {
   2126                             synchronized(this) {
   2127                                 final long now = SystemClock.uptimeMillis();
   2128                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2129                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2130                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2131                                 //        + ", write delay=" + nextWriteDelay);
   2132                                 if (nextWriteDelay < nextCpuDelay) {
   2133                                     nextCpuDelay = nextWriteDelay;
   2134                                 }
   2135                                 if (nextCpuDelay > 0) {
   2136                                     mProcessCpuMutexFree.set(true);
   2137                                     this.wait(nextCpuDelay);
   2138                                 }
   2139                             }
   2140                         } catch (InterruptedException e) {
   2141                         }
   2142                         updateCpuStatsNow();
   2143                     } catch (Exception e) {
   2144                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2145                     }
   2146                 }
   2147             }
   2148         };
   2149 
   2150         Watchdog.getInstance().addMonitor(this);
   2151         Watchdog.getInstance().addThread(mHandler);
   2152     }
   2153 
   2154     public void setSystemServiceManager(SystemServiceManager mgr) {
   2155         mSystemServiceManager = mgr;
   2156     }
   2157 
   2158     public void setInstaller(Installer installer) {
   2159         mInstaller = installer;
   2160     }
   2161 
   2162     private void start() {
   2163         Process.removeAllProcessGroups();
   2164         mProcessCpuThread.start();
   2165 
   2166         mBatteryStatsService.publish(mContext);
   2167         mAppOpsService.publish(mContext);
   2168         Slog.d("AppOps", "AppOpsService published");
   2169         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2170     }
   2171 
   2172     public void initPowerManagement() {
   2173         mStackSupervisor.initPowerManagement();
   2174         mBatteryStatsService.initPowerManagement();
   2175     }
   2176 
   2177     @Override
   2178     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2179             throws RemoteException {
   2180         if (code == SYSPROPS_TRANSACTION) {
   2181             // We need to tell all apps about the system property change.
   2182             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2183             synchronized(this) {
   2184                 final int NP = mProcessNames.getMap().size();
   2185                 for (int ip=0; ip<NP; ip++) {
   2186                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2187                     final int NA = apps.size();
   2188                     for (int ia=0; ia<NA; ia++) {
   2189                         ProcessRecord app = apps.valueAt(ia);
   2190                         if (app.thread != null) {
   2191                             procs.add(app.thread.asBinder());
   2192                         }
   2193                     }
   2194                 }
   2195             }
   2196 
   2197             int N = procs.size();
   2198             for (int i=0; i<N; i++) {
   2199                 Parcel data2 = Parcel.obtain();
   2200                 try {
   2201                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2202                 } catch (RemoteException e) {
   2203                 }
   2204                 data2.recycle();
   2205             }
   2206         }
   2207         try {
   2208             return super.onTransact(code, data, reply, flags);
   2209         } catch (RuntimeException e) {
   2210             // The activity manager only throws security exceptions, so let's
   2211             // log all others.
   2212             if (!(e instanceof SecurityException)) {
   2213                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2214             }
   2215             throw e;
   2216         }
   2217     }
   2218 
   2219     void updateCpuStats() {
   2220         final long now = SystemClock.uptimeMillis();
   2221         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2222             return;
   2223         }
   2224         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2225             synchronized (mProcessCpuThread) {
   2226                 mProcessCpuThread.notify();
   2227             }
   2228         }
   2229     }
   2230 
   2231     void updateCpuStatsNow() {
   2232         synchronized (mProcessCpuTracker) {
   2233             mProcessCpuMutexFree.set(false);
   2234             final long now = SystemClock.uptimeMillis();
   2235             boolean haveNewCpuStats = false;
   2236 
   2237             if (MONITOR_CPU_USAGE &&
   2238                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2239                 mLastCpuTime.set(now);
   2240                 haveNewCpuStats = true;
   2241                 mProcessCpuTracker.update();
   2242                 //Slog.i(TAG, mProcessCpu.printCurrentState());
   2243                 //Slog.i(TAG, "Total CPU usage: "
   2244                 //        + mProcessCpu.getTotalCpuPercent() + "%");
   2245 
   2246                 // Slog the cpu usage if the property is set.
   2247                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   2248                     int user = mProcessCpuTracker.getLastUserTime();
   2249                     int system = mProcessCpuTracker.getLastSystemTime();
   2250                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2251                     int irq = mProcessCpuTracker.getLastIrqTime();
   2252                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2253                     int idle = mProcessCpuTracker.getLastIdleTime();
   2254 
   2255                     int total = user + system + iowait + irq + softIrq + idle;
   2256                     if (total == 0) total = 1;
   2257 
   2258                     EventLog.writeEvent(EventLogTags.CPU,
   2259                             ((user+system+iowait+irq+softIrq) * 100) / total,
   2260                             (user * 100) / total,
   2261                             (system * 100) / total,
   2262                             (iowait * 100) / total,
   2263                             (irq * 100) / total,
   2264                             (softIrq * 100) / total);
   2265                 }
   2266             }
   2267 
   2268             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
   2269             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2270             synchronized(bstats) {
   2271                 synchronized(mPidsSelfLocked) {
   2272                     if (haveNewCpuStats) {
   2273                         if (mOnBattery) {
   2274                             int perc = bstats.startAddingCpuLocked();
   2275                             int totalUTime = 0;
   2276                             int totalSTime = 0;
   2277                             final int N = mProcessCpuTracker.countStats();
   2278                             for (int i=0; i<N; i++) {
   2279                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2280                                 if (!st.working) {
   2281                                     continue;
   2282                                 }
   2283                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2284                                 int otherUTime = (st.rel_utime*perc)/100;
   2285                                 int otherSTime = (st.rel_stime*perc)/100;
   2286                                 totalUTime += otherUTime;
   2287                                 totalSTime += otherSTime;
   2288                                 if (pr != null) {
   2289                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   2290                                     if (ps == null || !ps.isActive()) {
   2291                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   2292                                                 pr.info.uid, pr.processName);
   2293                                     }
   2294                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2295                                             st.rel_stime-otherSTime);
   2296                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2297                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   2298                                 } else {
   2299                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2300                                     if (ps == null || !ps.isActive()) {
   2301                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   2302                                                 bstats.mapUid(st.uid), st.name);
   2303                                     }
   2304                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2305                                             st.rel_stime-otherSTime);
   2306                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2307                                 }
   2308                             }
   2309                             bstats.finishAddingCpuLocked(perc, totalUTime,
   2310                                     totalSTime, cpuSpeedTimes);
   2311                         }
   2312                     }
   2313                 }
   2314 
   2315                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2316                     mLastWriteTime = now;
   2317                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2318                 }
   2319             }
   2320         }
   2321     }
   2322 
   2323     @Override
   2324     public void batteryNeedsCpuUpdate() {
   2325         updateCpuStatsNow();
   2326     }
   2327 
   2328     @Override
   2329     public void batteryPowerChanged(boolean onBattery) {
   2330         // When plugging in, update the CPU stats first before changing
   2331         // the plug state.
   2332         updateCpuStatsNow();
   2333         synchronized (this) {
   2334             synchronized(mPidsSelfLocked) {
   2335                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2336             }
   2337         }
   2338     }
   2339 
   2340     /**
   2341      * Initialize the application bind args. These are passed to each
   2342      * process when the bindApplication() IPC is sent to the process. They're
   2343      * lazily setup to make sure the services are running when they're asked for.
   2344      */
   2345     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
   2346         if (mAppBindArgs == null) {
   2347             mAppBindArgs = new HashMap<>();
   2348 
   2349             // Isolated processes won't get this optimization, so that we don't
   2350             // violate the rules about which services they have access to.
   2351             if (!isolated) {
   2352                 // Setup the application init args
   2353                 mAppBindArgs.put("package", ServiceManager.getService("package"));
   2354                 mAppBindArgs.put("window", ServiceManager.getService("window"));
   2355                 mAppBindArgs.put(Context.ALARM_SERVICE,
   2356                         ServiceManager.getService(Context.ALARM_SERVICE));
   2357             }
   2358         }
   2359         return mAppBindArgs;
   2360     }
   2361 
   2362     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
   2363         if (mFocusedActivity != r) {
   2364             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
   2365             mFocusedActivity = r;
   2366             if (r.task != null && r.task.voiceInteractor != null) {
   2367                 startRunningVoiceLocked();
   2368             } else {
   2369                 finishRunningVoiceLocked();
   2370             }
   2371             mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
   2372             if (r != null) {
   2373                 mWindowManager.setFocusedApp(r.appToken, true);
   2374             }
   2375             applyUpdateLockStateLocked(r);
   2376         }
   2377         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
   2378                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
   2379     }
   2380 
   2381     final void clearFocusedActivity(ActivityRecord r) {
   2382         if (mFocusedActivity == r) {
   2383             mFocusedActivity = null;
   2384         }
   2385     }
   2386 
   2387     @Override
   2388     public void setFocusedStack(int stackId) {
   2389         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
   2390         synchronized (ActivityManagerService.this) {
   2391             ActivityStack stack = mStackSupervisor.getStack(stackId);
   2392             if (stack != null) {
   2393                 ActivityRecord r = stack.topRunningActivityLocked(null);
   2394                 if (r != null) {
   2395                     setFocusedActivityLocked(r, "setFocusedStack");
   2396                 }
   2397             }
   2398         }
   2399     }
   2400 
   2401     /** Sets the task stack listener that gets callbacks when a task stack changes. */
   2402     @Override
   2403     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
   2404         synchronized (ActivityManagerService.this) {
   2405             if (listener != null) {
   2406                 mTaskStackListeners.register(listener);
   2407             }
   2408         }
   2409     }
   2410 
   2411     @Override
   2412     public void notifyActivityDrawn(IBinder token) {
   2413         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
   2414         synchronized (this) {
   2415             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
   2416             if (r != null) {
   2417                 r.task.stack.notifyActivityDrawnLocked(r);
   2418             }
   2419         }
   2420     }
   2421 
   2422     final void applyUpdateLockStateLocked(ActivityRecord r) {
   2423         // Modifications to the UpdateLock state are done on our handler, outside
   2424         // the activity manager's locks.  The new state is determined based on the
   2425         // state *now* of the relevant activity record.  The object is passed to
   2426         // the handler solely for logging detail, not to be consulted/modified.
   2427         final boolean nextState = r != null && r.immersive;
   2428         mHandler.sendMessage(
   2429                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   2430     }
   2431 
   2432     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   2433         Message msg = Message.obtain();
   2434         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
   2435         msg.obj = r.task.askedCompatMode ? null : r;
   2436         mHandler.sendMessage(msg);
   2437     }
   2438 
   2439     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   2440             String what, Object obj, ProcessRecord srcApp) {
   2441         app.lastActivityTime = now;
   2442 
   2443         if (app.activities.size() > 0) {
   2444             // Don't want to touch dependent processes that are hosting activities.
   2445             return index;
   2446         }
   2447 
   2448         int lrui = mLruProcesses.lastIndexOf(app);
   2449         if (lrui < 0) {
   2450             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   2451                     + what + " " + obj + " from " + srcApp);
   2452             return index;
   2453         }
   2454 
   2455         if (lrui >= index) {
   2456             // Don't want to cause this to move dependent processes *back* in the
   2457             // list as if they were less frequently used.
   2458             return index;
   2459         }
   2460 
   2461         if (lrui >= mLruProcessActivityStart) {
   2462             // Don't want to touch dependent processes that are hosting activities.
   2463             return index;
   2464         }
   2465 
   2466         mLruProcesses.remove(lrui);
   2467         if (index > 0) {
   2468             index--;
   2469         }
   2470         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
   2471                 + " in LRU list: " + app);
   2472         mLruProcesses.add(index, app);
   2473         return index;
   2474     }
   2475 
   2476     final void removeLruProcessLocked(ProcessRecord app) {
   2477         int lrui = mLruProcesses.lastIndexOf(app);
   2478         if (lrui >= 0) {
   2479             if (!app.killed) {
   2480                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   2481                 Process.killProcessQuiet(app.pid);
   2482                 Process.killProcessGroup(app.info.uid, app.pid);
   2483             }
   2484             if (lrui <= mLruProcessActivityStart) {
   2485                 mLruProcessActivityStart--;
   2486             }
   2487             if (lrui <= mLruProcessServiceStart) {
   2488                 mLruProcessServiceStart--;
   2489             }
   2490             mLruProcesses.remove(lrui);
   2491         }
   2492     }
   2493 
   2494     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   2495             ProcessRecord client) {
   2496         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   2497                 || app.treatLikeActivity;
   2498         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   2499         if (!activityChange && hasActivity) {
   2500             // The process has activities, so we are only allowing activity-based adjustments
   2501             // to move it.  It should be kept in the front of the list with other
   2502             // processes that have activities, and we don't want those to change their
   2503             // order except due to activity operations.
   2504             return;
   2505         }
   2506 
   2507         mLruSeq++;
   2508         final long now = SystemClock.uptimeMillis();
   2509         app.lastActivityTime = now;
   2510 
   2511         // First a quick reject: if the app is already at the position we will
   2512         // put it, then there is nothing to do.
   2513         if (hasActivity) {
   2514             final int N = mLruProcesses.size();
   2515             if (N > 0 && mLruProcesses.get(N-1) == app) {
   2516                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
   2517                 return;
   2518             }
   2519         } else {
   2520             if (mLruProcessServiceStart > 0
   2521                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   2522                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
   2523                 return;
   2524             }
   2525         }
   2526 
   2527         int lrui = mLruProcesses.lastIndexOf(app);
   2528 
   2529         if (app.persistent && lrui >= 0) {
   2530             // We don't care about the position of persistent processes, as long as
   2531             // they are in the list.
   2532             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
   2533             return;
   2534         }
   2535 
   2536         /* In progress: compute new position first, so we can avoid doing work
   2537            if the process is not actually going to move.  Not yet working.
   2538         int addIndex;
   2539         int nextIndex;
   2540         boolean inActivity = false, inService = false;
   2541         if (hasActivity) {
   2542             // Process has activities, put it at the very tipsy-top.
   2543             addIndex = mLruProcesses.size();
   2544             nextIndex = mLruProcessServiceStart;
   2545             inActivity = true;
   2546         } else if (hasService) {
   2547             // Process has services, put it at the top of the service list.
   2548             addIndex = mLruProcessActivityStart;
   2549             nextIndex = mLruProcessServiceStart;
   2550             inActivity = true;
   2551             inService = true;
   2552         } else  {
   2553             // Process not otherwise of interest, it goes to the top of the non-service area.
   2554             addIndex = mLruProcessServiceStart;
   2555             if (client != null) {
   2556                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2557                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   2558                         + app);
   2559                 if (clientIndex >= 0 && addIndex > clientIndex) {
   2560                     addIndex = clientIndex;
   2561                 }
   2562             }
   2563             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   2564         }
   2565 
   2566         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   2567                 + mLruProcessActivityStart + "): " + app);
   2568         */
   2569 
   2570         if (lrui >= 0) {
   2571             if (lrui < mLruProcessActivityStart) {
   2572                 mLruProcessActivityStart--;
   2573             }
   2574             if (lrui < mLruProcessServiceStart) {
   2575                 mLruProcessServiceStart--;
   2576             }
   2577             /*
   2578             if (addIndex > lrui) {
   2579                 addIndex--;
   2580             }
   2581             if (nextIndex > lrui) {
   2582                 nextIndex--;
   2583             }
   2584             */
   2585             mLruProcesses.remove(lrui);
   2586         }
   2587 
   2588         /*
   2589         mLruProcesses.add(addIndex, app);
   2590         if (inActivity) {
   2591             mLruProcessActivityStart++;
   2592         }
   2593         if (inService) {
   2594             mLruProcessActivityStart++;
   2595         }
   2596         */
   2597 
   2598         int nextIndex;
   2599         if (hasActivity) {
   2600             final int N = mLruProcesses.size();
   2601             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
   2602                 // Process doesn't have activities, but has clients with
   2603                 // activities...  move it up, but one below the top (the top
   2604                 // should always have a real activity).
   2605                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
   2606                 mLruProcesses.add(N-1, app);
   2607                 // To keep it from spamming the LRU list (by making a bunch of clients),
   2608                 // we will push down any other entries owned by the app.
   2609                 final int uid = app.info.uid;
   2610                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
   2611                     ProcessRecord subProc = mLruProcesses.get(i);
   2612                     if (subProc.info.uid == uid) {
   2613                         // We want to push this one down the list.  If the process after
   2614                         // it is for the same uid, however, don't do so, because we don't
   2615                         // want them internally to be re-ordered.
   2616                         if (mLruProcesses.get(i-1).info.uid != uid) {
   2617                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
   2618                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
   2619                             ProcessRecord tmp = mLruProcesses.get(i);
   2620                             mLruProcesses.set(i, mLruProcesses.get(i-1));
   2621                             mLruProcesses.set(i-1, tmp);
   2622                             i--;
   2623                         }
   2624                     } else {
   2625                         // A gap, we can stop here.
   2626                         break;
   2627                     }
   2628                 }
   2629             } else {
   2630                 // Process has activities, put it at the very tipsy-top.
   2631                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
   2632                 mLruProcesses.add(app);
   2633             }
   2634             nextIndex = mLruProcessServiceStart;
   2635         } else if (hasService) {
   2636             // Process has services, put it at the top of the service list.
   2637             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
   2638             mLruProcesses.add(mLruProcessActivityStart, app);
   2639             nextIndex = mLruProcessServiceStart;
   2640             mLruProcessActivityStart++;
   2641         } else  {
   2642             // Process not otherwise of interest, it goes to the top of the non-service area.
   2643             int index = mLruProcessServiceStart;
   2644             if (client != null) {
   2645                 // If there is a client, don't allow the process to be moved up higher
   2646                 // in the list than that client.
   2647                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2648                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
   2649                         + " when updating " + app);
   2650                 if (clientIndex <= lrui) {
   2651                     // Don't allow the client index restriction to push it down farther in the
   2652                     // list than it already is.
   2653                     clientIndex = lrui;
   2654                 }
   2655                 if (clientIndex >= 0 && index > clientIndex) {
   2656                     index = clientIndex;
   2657                 }
   2658             }
   2659             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
   2660             mLruProcesses.add(index, app);
   2661             nextIndex = index-1;
   2662             mLruProcessActivityStart++;
   2663             mLruProcessServiceStart++;
   2664         }
   2665 
   2666         // If the app is currently using a content provider or service,
   2667         // bump those processes as well.
   2668         for (int j=app.connections.size()-1; j>=0; j--) {
   2669             ConnectionRecord cr = app.connections.valueAt(j);
   2670             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   2671                     && cr.binding.service.app != null
   2672                     && cr.binding.service.app.lruSeq != mLruSeq
   2673                     && !cr.binding.service.app.persistent) {
   2674                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   2675                         "service connection", cr, app);
   2676             }
   2677         }
   2678         for (int j=app.conProviders.size()-1; j>=0; j--) {
   2679             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   2680             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   2681                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   2682                         "provider reference", cpr, app);
   2683             }
   2684         }
   2685     }
   2686 
   2687     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   2688         if (uid == Process.SYSTEM_UID) {
   2689             // The system gets to run in any process.  If there are multiple
   2690             // processes with the same uid, just pick the first (this
   2691             // should never happen).
   2692             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   2693             if (procs == null) return null;
   2694             final int procCount = procs.size();
   2695             for (int i = 0; i < procCount; i++) {
   2696                 final int procUid = procs.keyAt(i);
   2697                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
   2698                     // Don't use an app process or different user process for system component.
   2699                     continue;
   2700                 }
   2701                 return procs.valueAt(i);
   2702             }
   2703         }
   2704         ProcessRecord proc = mProcessNames.get(processName, uid);
   2705         if (false && proc != null && !keepIfLarge
   2706                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   2707                 && proc.lastCachedPss >= 4000) {
   2708             // Turn this condition on to cause killing to happen regularly, for testing.
   2709             if (proc.baseProcessTracker != null) {
   2710                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2711             }
   2712             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2713         } else if (proc != null && !keepIfLarge
   2714                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   2715                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2716             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   2717             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   2718                 if (proc.baseProcessTracker != null) {
   2719                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2720                 }
   2721                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2722             }
   2723         }
   2724         return proc;
   2725     }
   2726 
   2727     void ensurePackageDexOpt(String packageName) {
   2728         IPackageManager pm = AppGlobals.getPackageManager();
   2729         try {
   2730             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
   2731                 mDidDexOpt = true;
   2732             }
   2733         } catch (RemoteException e) {
   2734         }
   2735     }
   2736 
   2737     boolean isNextTransitionForward() {
   2738         int transit = mWindowManager.getPendingAppTransition();
   2739         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2740                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2741                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2742     }
   2743 
   2744     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   2745             String processName, String abiOverride, int uid, Runnable crashHandler) {
   2746         synchronized(this) {
   2747             ApplicationInfo info = new ApplicationInfo();
   2748             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   2749             // For isolated processes, the former contains the parent's uid and the latter the
   2750             // actual uid of the isolated process.
   2751             // In the special case introduced by this method (which is, starting an isolated
   2752             // process directly from the SystemServer without an actual parent app process) the
   2753             // closest thing to a parent's uid is SYSTEM_UID.
   2754             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   2755             // the |isolated| logic in the ProcessRecord constructor.
   2756             info.uid = Process.SYSTEM_UID;
   2757             info.processName = processName;
   2758             info.className = entryPoint;
   2759             info.packageName = "android";
   2760             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   2761                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   2762                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   2763                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   2764                     crashHandler);
   2765             return proc != null ? proc.pid : 0;
   2766         }
   2767     }
   2768 
   2769     final ProcessRecord startProcessLocked(String processName,
   2770             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2771             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2772             boolean isolated, boolean keepIfLarge) {
   2773         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   2774                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   2775                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   2776                 null /* crashHandler */);
   2777     }
   2778 
   2779     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   2780             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   2781             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   2782             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   2783         long startTime = SystemClock.elapsedRealtime();
   2784         ProcessRecord app;
   2785         if (!isolated) {
   2786             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   2787             checkTime(startTime, "startProcess: after getProcessRecord");
   2788         } else {
   2789             // If this is an isolated process, it can't re-use an existing process.
   2790             app = null;
   2791         }
   2792         // We don't have to do anything more if:
   2793         // (1) There is an existing application record; and
   2794         // (2) The caller doesn't think it is dead, OR there is no thread
   2795         //     object attached to it so we know it couldn't have crashed; and
   2796         // (3) There is a pid assigned to it, so it is either starting or
   2797         //     already running.
   2798         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2799                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2800                 + " thread=" + (app != null ? app.thread : null)
   2801                 + " pid=" + (app != null ? app.pid : -1));
   2802         if (app != null && app.pid > 0) {
   2803             if (!knownToBeDead || app.thread == null) {
   2804                 // We already have the app running, or are waiting for it to
   2805                 // come up (we have a pid but not yet its thread), so keep it.
   2806                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2807                 // If this is a new package in the process, add the package to the list
   2808                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   2809                 checkTime(startTime, "startProcess: done, added package to proc");
   2810                 return app;
   2811             }
   2812 
   2813             // An application record is attached to a previous process,
   2814             // clean it up now.
   2815             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2816             checkTime(startTime, "startProcess: bad proc running, killing");
   2817             Process.killProcessGroup(app.info.uid, app.pid);
   2818             handleAppDiedLocked(app, true, true);
   2819             checkTime(startTime, "startProcess: done killing old proc");
   2820         }
   2821 
   2822         String hostingNameStr = hostingName != null
   2823                 ? hostingName.flattenToShortString() : null;
   2824 
   2825         if (!isolated) {
   2826             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   2827                 // If we are in the background, then check to see if this process
   2828                 // is bad.  If so, we will just silently fail.
   2829                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2830                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   2831                             + "/" + info.processName);
   2832                     return null;
   2833                 }
   2834             } else {
   2835                 // When the user is explicitly starting a process, then clear its
   2836                 // crash count so that we won't make it bad until they see at
   2837                 // least one crash dialog again, and make the process good again
   2838                 // if it had been bad.
   2839                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   2840                         + "/" + info.processName);
   2841                 mProcessCrashTimes.remove(info.processName, info.uid);
   2842                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2843                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2844                             UserHandle.getUserId(info.uid), info.uid,
   2845                             info.processName);
   2846                     mBadProcesses.remove(info.processName, info.uid);
   2847                     if (app != null) {
   2848                         app.bad = false;
   2849                     }
   2850                 }
   2851             }
   2852         }
   2853 
   2854         if (app == null) {
   2855             checkTime(startTime, "startProcess: creating new process record");
   2856             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   2857             if (app == null) {
   2858                 Slog.w(TAG, "Failed making new process record for "
   2859                         + processName + "/" + info.uid + " isolated=" + isolated);
   2860                 return null;
   2861             }
   2862             app.crashHandler = crashHandler;
   2863             mProcessNames.put(processName, app.uid, app);
   2864             if (isolated) {
   2865                 mIsolatedProcesses.put(app.uid, app);
   2866             }
   2867             checkTime(startTime, "startProcess: done creating new process record");
   2868         } else {
   2869             // If this is a new package in the process, add the package to the list
   2870             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   2871             checkTime(startTime, "startProcess: added package to existing proc");
   2872         }
   2873 
   2874         // If the system is not ready yet, then hold off on starting this
   2875         // process until it is.
   2876         if (!mProcessesReady
   2877                 && !isAllowedWhileBooting(info)
   2878                 && !allowWhileBooting) {
   2879             if (!mProcessesOnHold.contains(app)) {
   2880                 mProcessesOnHold.add(app);
   2881             }
   2882             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2883             checkTime(startTime, "startProcess: returning with proc on hold");
   2884             return app;
   2885         }
   2886 
   2887         checkTime(startTime, "startProcess: stepping in to startProcess");
   2888         startProcessLocked(
   2889                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   2890         checkTime(startTime, "startProcess: done starting proc!");
   2891         return (app.pid != 0) ? app : null;
   2892     }
   2893 
   2894     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2895         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2896     }
   2897 
   2898     private final void startProcessLocked(ProcessRecord app,
   2899             String hostingType, String hostingNameStr) {
   2900         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   2901                 null /* entryPoint */, null /* entryPointArgs */);
   2902     }
   2903 
   2904     private final void startProcessLocked(ProcessRecord app, String hostingType,
   2905             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   2906         long startTime = SystemClock.elapsedRealtime();
   2907         if (app.pid > 0 && app.pid != MY_PID) {
   2908             checkTime(startTime, "startProcess: removing from pids map");
   2909             synchronized (mPidsSelfLocked) {
   2910                 mPidsSelfLocked.remove(app.pid);
   2911                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2912             }
   2913             checkTime(startTime, "startProcess: done removing from pids map");
   2914             app.setPid(0);
   2915         }
   2916 
   2917         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2918                 "startProcessLocked removing on hold: " + app);
   2919         mProcessesOnHold.remove(app);
   2920 
   2921         checkTime(startTime, "startProcess: starting to update cpu stats");
   2922         updateCpuStats();
   2923         checkTime(startTime, "startProcess: done updating cpu stats");
   2924 
   2925         try {
   2926             int uid = app.uid;
   2927 
   2928             int[] gids = null;
   2929             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2930             if (!app.isolated) {
   2931                 int[] permGids = null;
   2932                 try {
   2933                     checkTime(startTime, "startProcess: getting gids from package manager");
   2934                     final PackageManager pm = mContext.getPackageManager();
   2935                     permGids = pm.getPackageGids(app.info.packageName);
   2936 
   2937                     if (Environment.isExternalStorageEmulated()) {
   2938                         checkTime(startTime, "startProcess: checking external storage perm");
   2939                         if (pm.checkPermission(
   2940                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2941                                 app.info.packageName) == PERMISSION_GRANTED) {
   2942                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2943                         } else {
   2944                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2945                         }
   2946                     }
   2947                 } catch (PackageManager.NameNotFoundException e) {
   2948                     Slog.w(TAG, "Unable to retrieve gids", e);
   2949                 }
   2950 
   2951                 /*
   2952                  * Add shared application and profile GIDs so applications can share some
   2953                  * resources like shared libraries and access user-wide resources
   2954                  */
   2955                 if (permGids == null) {
   2956                     gids = new int[2];
   2957                 } else {
   2958                     gids = new int[permGids.length + 2];
   2959                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   2960                 }
   2961                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2962                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   2963             }
   2964             checkTime(startTime, "startProcess: building args");
   2965             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   2966                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   2967                         && mTopComponent != null
   2968                         && app.processName.equals(mTopComponent.getPackageName())) {
   2969                     uid = 0;
   2970                 }
   2971                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   2972                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2973                     uid = 0;
   2974                 }
   2975             }
   2976             int debugFlags = 0;
   2977             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2978                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2979                 // Also turn on CheckJNI for debuggable apps. It's quite
   2980                 // awkward to turn on otherwise.
   2981                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2982             }
   2983             // Run the app in safe mode if its manifest requests so or the
   2984             // system is booted in safe mode.
   2985             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2986                 mSafeMode == true) {
   2987                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2988             }
   2989             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2990                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2991             }
   2992             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2993                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2994             }
   2995             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2996                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2997             }
   2998 
   2999             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3000             if (requiredAbi == null) {
   3001                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3002             }
   3003 
   3004             String instructionSet = null;
   3005             if (app.info.primaryCpuAbi != null) {
   3006                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3007             }
   3008 
   3009             app.gids = gids;
   3010             app.requiredAbi = requiredAbi;
   3011             app.instructionSet = instructionSet;
   3012 
   3013             // Start the process.  It will either succeed and return a result containing
   3014             // the PID of the new process, or else throw a RuntimeException.
   3015             boolean isActivityProcess = (entryPoint == null);
   3016             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3017             checkTime(startTime, "startProcess: asking zygote to start proc");
   3018             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3019                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3020                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3021                     app.info.dataDir, entryPointArgs);
   3022             checkTime(startTime, "startProcess: returned from zygote!");
   3023 
   3024             if (app.isolated) {
   3025                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
   3026             }
   3027             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3028             checkTime(startTime, "startProcess: done updating battery stats");
   3029 
   3030             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3031                     UserHandle.getUserId(uid), startResult.pid, uid,
   3032                     app.processName, hostingType,
   3033                     hostingNameStr != null ? hostingNameStr : "");
   3034 
   3035             if (app.persistent) {
   3036                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3037             }
   3038 
   3039             checkTime(startTime, "startProcess: building log message");
   3040             StringBuilder buf = mStringBuilder;
   3041             buf.setLength(0);
   3042             buf.append("Start proc ");
   3043             buf.append(startResult.pid);
   3044             buf.append(':');
   3045             buf.append(app.processName);
   3046             buf.append('/');
   3047             UserHandle.formatUid(buf, uid);
   3048             if (!isActivityProcess) {
   3049                 buf.append(" [");
   3050                 buf.append(entryPoint);
   3051                 buf.append("]");
   3052             }
   3053             buf.append(" for ");
   3054             buf.append(hostingType);
   3055             if (hostingNameStr != null) {
   3056                 buf.append(" ");
   3057                 buf.append(hostingNameStr);
   3058             }
   3059             Slog.i(TAG, buf.toString());
   3060             app.setPid(startResult.pid);
   3061             app.usingWrapper = startResult.usingWrapper;
   3062             app.removed = false;
   3063             app.killed = false;
   3064             app.killedByAm = false;
   3065             checkTime(startTime, "startProcess: starting to update pids map");
   3066             synchronized (mPidsSelfLocked) {
   3067                 this.mPidsSelfLocked.put(startResult.pid, app);
   3068                 if (isActivityProcess) {
   3069                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3070                     msg.obj = app;
   3071                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3072                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3073                 }
   3074             }
   3075             checkTime(startTime, "startProcess: done updating pids map");
   3076         } catch (RuntimeException e) {
   3077             // XXX do better error recovery.
   3078             app.setPid(0);
   3079             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   3080             if (app.isolated) {
   3081                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   3082             }
   3083             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3084         }
   3085     }
   3086 
   3087     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3088         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
   3089         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3090         if (resumed) {
   3091             if (mUsageStatsService != null) {
   3092                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3093                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3094             }
   3095             synchronized (stats) {
   3096                 stats.noteActivityResumedLocked(component.app.uid);
   3097             }
   3098         } else {
   3099             if (mUsageStatsService != null) {
   3100                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3101                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3102             }
   3103             synchronized (stats) {
   3104                 stats.noteActivityPausedLocked(component.app.uid);
   3105             }
   3106         }
   3107     }
   3108 
   3109     Intent getHomeIntent() {
   3110         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3111         intent.setComponent(mTopComponent);
   3112         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3113             intent.addCategory(Intent.CATEGORY_HOME);
   3114         }
   3115         return intent;
   3116     }
   3117 
   3118     boolean startHomeActivityLocked(int userId, String reason) {
   3119         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3120                 && mTopAction == null) {
   3121             // We are running in factory test mode, but unable to find
   3122             // the factory test app, so just sit around displaying the
   3123             // error message and don't try to start anything.
   3124             return false;
   3125         }
   3126         Intent intent = getHomeIntent();
   3127         ActivityInfo aInfo =
   3128             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3129         if (aInfo != null) {
   3130             intent.setComponent(new ComponentName(
   3131                     aInfo.applicationInfo.packageName, aInfo.name));
   3132             // Don't do this if the home app is currently being
   3133             // instrumented.
   3134             aInfo = new ActivityInfo(aInfo);
   3135             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3136             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3137                     aInfo.applicationInfo.uid, true);
   3138             if (app == null || app.instrumentationClass == null) {
   3139                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3140                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
   3141             }
   3142         }
   3143 
   3144         return true;
   3145     }
   3146 
   3147     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3148         ActivityInfo ai = null;
   3149         ComponentName comp = intent.getComponent();
   3150         try {
   3151             if (comp != null) {
   3152                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3153             } else {
   3154                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3155                         intent,
   3156                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3157                             flags, userId);
   3158 
   3159                 if (info != null) {
   3160                     ai = info.activityInfo;
   3161                 }
   3162             }
   3163         } catch (RemoteException e) {
   3164             // ignore
   3165         }
   3166 
   3167         return ai;
   3168     }
   3169 
   3170     /**
   3171      * Starts the "new version setup screen" if appropriate.
   3172      */
   3173     void startSetupActivityLocked() {
   3174         // Only do this once per boot.
   3175         if (mCheckedForSetup) {
   3176             return;
   3177         }
   3178 
   3179         // We will show this screen if the current one is a different
   3180         // version than the last one shown, and we are not running in
   3181         // low-level factory test mode.
   3182         final ContentResolver resolver = mContext.getContentResolver();
   3183         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3184                 Settings.Global.getInt(resolver,
   3185                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3186             mCheckedForSetup = true;
   3187 
   3188             // See if we should be showing the platform update setup UI.
   3189             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3190             List<ResolveInfo> ris = mContext.getPackageManager()
   3191                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   3192 
   3193             // We don't allow third party apps to replace this.
   3194             ResolveInfo ri = null;
   3195             for (int i=0; ris != null && i<ris.size(); i++) {
   3196                 if ((ris.get(i).activityInfo.applicationInfo.flags
   3197                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   3198                     ri = ris.get(i);
   3199                     break;
   3200                 }
   3201             }
   3202 
   3203             if (ri != null) {
   3204                 String vers = ri.activityInfo.metaData != null
   3205                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3206                         : null;
   3207                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   3208                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   3209                             Intent.METADATA_SETUP_VERSION);
   3210                 }
   3211                 String lastVers = Settings.Secure.getString(
   3212                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   3213                 if (vers != null && !vers.equals(lastVers)) {
   3214                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3215                     intent.setComponent(new ComponentName(
   3216                             ri.activityInfo.packageName, ri.activityInfo.name));
   3217                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
   3218                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
   3219                             null);
   3220                 }
   3221             }
   3222         }
   3223     }
   3224 
   3225     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   3226         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   3227     }
   3228 
   3229     void enforceNotIsolatedCaller(String caller) {
   3230         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   3231             throw new SecurityException("Isolated process not allowed to call " + caller);
   3232         }
   3233     }
   3234 
   3235     void enforceShellRestriction(String restriction, int userHandle) {
   3236         if (Binder.getCallingUid() == Process.SHELL_UID) {
   3237             if (userHandle < 0
   3238                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
   3239                 throw new SecurityException("Shell does not have permission to access user "
   3240                         + userHandle);
   3241             }
   3242         }
   3243     }
   3244 
   3245     @Override
   3246     public int getFrontActivityScreenCompatMode() {
   3247         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   3248         synchronized (this) {
   3249             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   3250         }
   3251     }
   3252 
   3253     @Override
   3254     public void setFrontActivityScreenCompatMode(int mode) {
   3255         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3256                 "setFrontActivityScreenCompatMode");
   3257         synchronized (this) {
   3258             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   3259         }
   3260     }
   3261 
   3262     @Override
   3263     public int getPackageScreenCompatMode(String packageName) {
   3264         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   3265         synchronized (this) {
   3266             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   3267         }
   3268     }
   3269 
   3270     @Override
   3271     public void setPackageScreenCompatMode(String packageName, int mode) {
   3272         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3273                 "setPackageScreenCompatMode");
   3274         synchronized (this) {
   3275             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   3276         }
   3277     }
   3278 
   3279     @Override
   3280     public boolean getPackageAskScreenCompat(String packageName) {
   3281         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   3282         synchronized (this) {
   3283             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   3284         }
   3285     }
   3286 
   3287     @Override
   3288     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   3289         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3290                 "setPackageAskScreenCompat");
   3291         synchronized (this) {
   3292             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   3293         }
   3294     }
   3295 
   3296     private void dispatchProcessesChanged() {
   3297         int N;
   3298         synchronized (this) {
   3299             N = mPendingProcessChanges.size();
   3300             if (mActiveProcessChanges.length < N) {
   3301                 mActiveProcessChanges = new ProcessChangeItem[N];
   3302             }
   3303             mPendingProcessChanges.toArray(mActiveProcessChanges);
   3304             mAvailProcessChanges.addAll(mPendingProcessChanges);
   3305             mPendingProcessChanges.clear();
   3306             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   3307         }
   3308 
   3309         int i = mProcessObservers.beginBroadcast();
   3310         while (i > 0) {
   3311             i--;
   3312             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3313             if (observer != null) {
   3314                 try {
   3315                     for (int j=0; j<N; j++) {
   3316                         ProcessChangeItem item = mActiveProcessChanges[j];
   3317                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   3318                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   3319                                     + item.pid + " uid=" + item.uid + ": "
   3320                                     + item.foregroundActivities);
   3321                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   3322                                     item.foregroundActivities);
   3323                         }
   3324                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   3325                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
   3326                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
   3327                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   3328                         }
   3329                     }
   3330                 } catch (RemoteException e) {
   3331                 }
   3332             }
   3333         }
   3334         mProcessObservers.finishBroadcast();
   3335     }
   3336 
   3337     private void dispatchProcessDied(int pid, int uid) {
   3338         int i = mProcessObservers.beginBroadcast();
   3339         while (i > 0) {
   3340             i--;
   3341             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3342             if (observer != null) {
   3343                 try {
   3344                     observer.onProcessDied(pid, uid);
   3345                 } catch (RemoteException e) {
   3346                 }
   3347             }
   3348         }
   3349         mProcessObservers.finishBroadcast();
   3350     }
   3351 
   3352     @Override
   3353     public final int startActivity(IApplicationThread caller, String callingPackage,
   3354             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3355             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
   3356         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   3357             resultWho, requestCode, startFlags, profilerInfo, options,
   3358             UserHandle.getCallingUserId());
   3359     }
   3360 
   3361     @Override
   3362     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   3363             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3364             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3365         enforceNotIsolatedCaller("startActivity");
   3366         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3367                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3368         // TODO: Switch to user app stacks here.
   3369         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3370                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3371                 profilerInfo, null, null, options, userId, null, null);
   3372     }
   3373 
   3374     @Override
   3375     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   3376             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3377             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3378 
   3379         // This is very dangerous -- it allows you to perform a start activity (including
   3380         // permission grants) as any app that may launch one of your own activities.  So
   3381         // we will only allow this to be done from activities that are part of the core framework,
   3382         // and then only when they are running as the system.
   3383         final ActivityRecord sourceRecord;
   3384         final int targetUid;
   3385         final String targetPackage;
   3386         synchronized (this) {
   3387             if (resultTo == null) {
   3388                 throw new SecurityException("Must be called from an activity");
   3389             }
   3390             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   3391             if (sourceRecord == null) {
   3392                 throw new SecurityException("Called with bad activity token: " + resultTo);
   3393             }
   3394             if (!sourceRecord.info.packageName.equals("android")) {
   3395                 throw new SecurityException(
   3396                         "Must be called from an activity that is declared in the android package");
   3397             }
   3398             if (sourceRecord.app == null) {
   3399                 throw new SecurityException("Called without a process attached to activity");
   3400             }
   3401             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   3402                 // This is still okay, as long as this activity is running under the
   3403                 // uid of the original calling activity.
   3404                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   3405                     throw new SecurityException(
   3406                             "Calling activity in uid " + sourceRecord.app.uid
   3407                                     + " must be system uid or original calling uid "
   3408                                     + sourceRecord.launchedFromUid);
   3409                 }
   3410             }
   3411             targetUid = sourceRecord.launchedFromUid;
   3412             targetPackage = sourceRecord.launchedFromPackage;
   3413         }
   3414 
   3415         if (userId == UserHandle.USER_NULL) {
   3416             userId = UserHandle.getUserId(sourceRecord.app.uid);
   3417         }
   3418 
   3419         // TODO: Switch to user app stacks here.
   3420         try {
   3421             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
   3422                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   3423                     null, null, options, userId, null, null);
   3424             return ret;
   3425         } catch (SecurityException e) {
   3426             // XXX need to figure out how to propagate to original app.
   3427             // A SecurityException here is generally actually a fault of the original
   3428             // calling activity (such as a fairly granting permissions), so propagate it
   3429             // back to them.
   3430             /*
   3431             StringBuilder msg = new StringBuilder();
   3432             msg.append("While launching");
   3433             msg.append(intent.toString());
   3434             msg.append(": ");
   3435             msg.append(e.getMessage());
   3436             */
   3437             throw e;
   3438         }
   3439     }
   3440 
   3441     @Override
   3442     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   3443             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3444             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3445         enforceNotIsolatedCaller("startActivityAndWait");
   3446         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3447                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   3448         WaitResult res = new WaitResult();
   3449         // TODO: Switch to user app stacks here.
   3450         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   3451                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   3452                 options, userId, null, null);
   3453         return res;
   3454     }
   3455 
   3456     @Override
   3457     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   3458             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3459             int startFlags, Configuration config, Bundle options, int userId) {
   3460         enforceNotIsolatedCaller("startActivityWithConfig");
   3461         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3462                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   3463         // TODO: Switch to user app stacks here.
   3464         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3465                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3466                 null, null, config, options, userId, null, null);
   3467         return ret;
   3468     }
   3469 
   3470     @Override
   3471     public int startActivityIntentSender(IApplicationThread caller,
   3472             IntentSender intent, Intent fillInIntent, String resolvedType,
   3473             IBinder resultTo, String resultWho, int requestCode,
   3474             int flagsMask, int flagsValues, Bundle options) {
   3475         enforceNotIsolatedCaller("startActivityIntentSender");
   3476         // Refuse possible leaked file descriptors
   3477         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3478             throw new IllegalArgumentException("File descriptors passed in Intent");
   3479         }
   3480 
   3481         IIntentSender sender = intent.getTarget();
   3482         if (!(sender instanceof PendingIntentRecord)) {
   3483             throw new IllegalArgumentException("Bad PendingIntent object");
   3484         }
   3485 
   3486         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3487 
   3488         synchronized (this) {
   3489             // If this is coming from the currently resumed activity, it is
   3490             // effectively saying that app switches are allowed at this point.
   3491             final ActivityStack stack = getFocusedStack();
   3492             if (stack.mResumedActivity != null &&
   3493                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   3494                 mAppSwitchesAllowedTime = 0;
   3495             }
   3496         }
   3497         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   3498                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
   3499         return ret;
   3500     }
   3501 
   3502     @Override
   3503     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   3504             Intent intent, String resolvedType, IVoiceInteractionSession session,
   3505             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   3506             Bundle options, int userId) {
   3507         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   3508                 != PackageManager.PERMISSION_GRANTED) {
   3509             String msg = "Permission Denial: startVoiceActivity() from pid="
   3510                     + Binder.getCallingPid()
   3511                     + ", uid=" + Binder.getCallingUid()
   3512                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   3513             Slog.w(TAG, msg);
   3514             throw new SecurityException(msg);
   3515         }
   3516         if (session == null || interactor == null) {
   3517             throw new NullPointerException("null session or interactor");
   3518         }
   3519         userId = handleIncomingUser(callingPid, callingUid, userId,
   3520                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
   3521         // TODO: Switch to user app stacks here.
   3522         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
   3523                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   3524                 null, options, userId, null, null);
   3525     }
   3526 
   3527     @Override
   3528     public boolean startNextMatchingActivity(IBinder callingActivity,
   3529             Intent intent, Bundle options) {
   3530         // Refuse possible leaked file descriptors
   3531         if (intent != null && intent.hasFileDescriptors() == true) {
   3532             throw new IllegalArgumentException("File descriptors passed in Intent");
   3533         }
   3534 
   3535         synchronized (this) {
   3536             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   3537             if (r == null) {
   3538                 ActivityOptions.abort(options);
   3539                 return false;
   3540             }
   3541             if (r.app == null || r.app.thread == null) {
   3542                 // The caller is not running...  d'oh!
   3543                 ActivityOptions.abort(options);
   3544                 return false;
   3545             }
   3546             intent = new Intent(intent);
   3547             // The caller is not allowed to change the data.
   3548             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3549             // And we are resetting to find the next component...
   3550             intent.setComponent(null);
   3551 
   3552             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3553 
   3554             ActivityInfo aInfo = null;
   3555             try {
   3556                 List<ResolveInfo> resolves =
   3557                     AppGlobals.getPackageManager().queryIntentActivities(
   3558                             intent, r.resolvedType,
   3559                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   3560                             UserHandle.getCallingUserId());
   3561 
   3562                 // Look for the original activity in the list...
   3563                 final int N = resolves != null ? resolves.size() : 0;
   3564                 for (int i=0; i<N; i++) {
   3565                     ResolveInfo rInfo = resolves.get(i);
   3566                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3567                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3568                         // We found the current one...  the next matching is
   3569                         // after it.
   3570                         i++;
   3571                         if (i<N) {
   3572                             aInfo = resolves.get(i).activityInfo;
   3573                         }
   3574                         if (debug) {
   3575                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   3576                                     + "/" + r.info.name);
   3577                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
   3578                                     + "/" + aInfo.name);
   3579                         }
   3580                         break;
   3581                     }
   3582                 }
   3583             } catch (RemoteException e) {
   3584             }
   3585 
   3586             if (aInfo == null) {
   3587                 // Nobody who is next!
   3588                 ActivityOptions.abort(options);
   3589                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   3590                 return false;
   3591             }
   3592 
   3593             intent.setComponent(new ComponentName(
   3594                     aInfo.applicationInfo.packageName, aInfo.name));
   3595             intent.setFlags(intent.getFlags()&~(
   3596                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3597                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3598                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3599                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3600 
   3601             // Okay now we need to start the new activity, replacing the
   3602             // currently running activity.  This is a little tricky because
   3603             // we want to start the new one as if the current one is finished,
   3604             // but not finish the current one first so that there is no flicker.
   3605             // And thus...
   3606             final boolean wasFinishing = r.finishing;
   3607             r.finishing = true;
   3608 
   3609             // Propagate reply information over to the new activity.
   3610             final ActivityRecord resultTo = r.resultTo;
   3611             final String resultWho = r.resultWho;
   3612             final int requestCode = r.requestCode;
   3613             r.resultTo = null;
   3614             if (resultTo != null) {
   3615                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3616             }
   3617 
   3618             final long origId = Binder.clearCallingIdentity();
   3619             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
   3620                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
   3621                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
   3622                     -1, r.launchedFromUid, 0, options, false, null, null, null);
   3623             Binder.restoreCallingIdentity(origId);
   3624 
   3625             r.finishing = wasFinishing;
   3626             if (res != ActivityManager.START_SUCCESS) {
   3627                 return false;
   3628             }
   3629             return true;
   3630         }
   3631     }
   3632 
   3633     @Override
   3634     public final int startActivityFromRecents(int taskId, Bundle options) {
   3635         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   3636             String msg = "Permission Denial: startActivityFromRecents called without " +
   3637                     START_TASKS_FROM_RECENTS;
   3638             Slog.w(TAG, msg);
   3639             throw new SecurityException(msg);
   3640         }
   3641         return startActivityFromRecentsInner(taskId, options);
   3642     }
   3643 
   3644     final int startActivityFromRecentsInner(int taskId, Bundle options) {
   3645         final TaskRecord task;
   3646         final int callingUid;
   3647         final String callingPackage;
   3648         final Intent intent;
   3649         final int userId;
   3650         synchronized (this) {
   3651             task = recentTaskForIdLocked(taskId);
   3652             if (task == null) {
   3653                 throw new IllegalArgumentException("Task " + taskId + " not found.");
   3654             }
   3655             if (task.getRootActivity() != null) {
   3656                 moveTaskToFrontLocked(task.taskId, 0, null);
   3657                 return ActivityManager.START_TASK_TO_FRONT;
   3658             }
   3659             callingUid = task.mCallingUid;
   3660             callingPackage = task.mCallingPackage;
   3661             intent = task.intent;
   3662             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
   3663             userId = task.userId;
   3664         }
   3665         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
   3666                 options, userId, null, task);
   3667     }
   3668 
   3669     final int startActivityInPackage(int uid, String callingPackage,
   3670             Intent intent, String resolvedType, IBinder resultTo,
   3671             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
   3672             IActivityContainer container, TaskRecord inTask) {
   3673 
   3674         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3675                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3676 
   3677         // TODO: Switch to user app stacks here.
   3678         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
   3679                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3680                 null, null, null, options, userId, container, inTask);
   3681         return ret;
   3682     }
   3683 
   3684     @Override
   3685     public final int startActivities(IApplicationThread caller, String callingPackage,
   3686             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   3687             int userId) {
   3688         enforceNotIsolatedCaller("startActivities");
   3689         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3690                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3691         // TODO: Switch to user app stacks here.
   3692         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
   3693                 resolvedTypes, resultTo, options, userId);
   3694         return ret;
   3695     }
   3696 
   3697     final int startActivitiesInPackage(int uid, String callingPackage,
   3698             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   3699             Bundle options, int userId) {
   3700 
   3701         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3702                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3703         // TODO: Switch to user app stacks here.
   3704         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   3705                 resultTo, options, userId);
   3706         return ret;
   3707     }
   3708 
   3709     //explicitly remove thd old information in mRecentTasks when removing existing user.
   3710     private void removeRecentTasksForUserLocked(int userId) {
   3711         if(userId <= 0) {
   3712             Slog.i(TAG, "Can't remove recent task on user " + userId);
   3713             return;
   3714         }
   3715 
   3716         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
   3717             TaskRecord tr = mRecentTasks.get(i);
   3718             if (tr.userId == userId) {
   3719                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
   3720                         + " when finishing user" + userId);
   3721                 mRecentTasks.remove(i);
   3722                 tr.removedFromRecents();
   3723             }
   3724         }
   3725 
   3726         // Remove tasks from persistent storage.
   3727         notifyTaskPersisterLocked(null, true);
   3728     }
   3729 
   3730     // Sort by taskId
   3731     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
   3732         @Override
   3733         public int compare(TaskRecord lhs, TaskRecord rhs) {
   3734             return rhs.taskId - lhs.taskId;
   3735         }
   3736     };
   3737 
   3738     // Extract the affiliates of the chain containing mRecentTasks[start].
   3739     private int processNextAffiliateChainLocked(int start) {
   3740         final TaskRecord startTask = mRecentTasks.get(start);
   3741         final int affiliateId = startTask.mAffiliatedTaskId;
   3742 
   3743         // Quick identification of isolated tasks. I.e. those not launched behind.
   3744         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
   3745                 startTask.mNextAffiliate == null) {
   3746             // There is still a slim chance that there are other tasks that point to this task
   3747             // and that the chain is so messed up that this task no longer points to them but
   3748             // the gain of this optimization outweighs the risk.
   3749             startTask.inRecents = true;
   3750             return start + 1;
   3751         }
   3752 
   3753         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
   3754         mTmpRecents.clear();
   3755         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
   3756             final TaskRecord task = mRecentTasks.get(i);
   3757             if (task.mAffiliatedTaskId == affiliateId) {
   3758                 mRecentTasks.remove(i);
   3759                 mTmpRecents.add(task);
   3760             }
   3761         }
   3762 
   3763         // Sort them all by taskId. That is the order they were create in and that order will
   3764         // always be correct.
   3765         Collections.sort(mTmpRecents, mTaskRecordComparator);
   3766 
   3767         // Go through and fix up the linked list.
   3768         // The first one is the end of the chain and has no next.
   3769         final TaskRecord first = mTmpRecents.get(0);
   3770         first.inRecents = true;
   3771         if (first.mNextAffiliate != null) {
   3772             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
   3773             first.setNextAffiliate(null);
   3774             notifyTaskPersisterLocked(first, false);
   3775         }
   3776         // Everything in the middle is doubly linked from next to prev.
   3777         final int tmpSize = mTmpRecents.size();
   3778         for (int i = 0; i < tmpSize - 1; ++i) {
   3779             final TaskRecord next = mTmpRecents.get(i);
   3780             final TaskRecord prev = mTmpRecents.get(i + 1);
   3781             if (next.mPrevAffiliate != prev) {
   3782                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
   3783                         " setting prev=" + prev);
   3784                 next.setPrevAffiliate(prev);
   3785                 notifyTaskPersisterLocked(next, false);
   3786             }
   3787             if (prev.mNextAffiliate != next) {
   3788                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
   3789                         " setting next=" + next);
   3790                 prev.setNextAffiliate(next);
   3791                 notifyTaskPersisterLocked(prev, false);
   3792             }
   3793             prev.inRecents = true;
   3794         }
   3795         // The last one is the beginning of the list and has no prev.
   3796         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
   3797         if (last.mPrevAffiliate != null) {
   3798             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
   3799             last.setPrevAffiliate(null);
   3800             notifyTaskPersisterLocked(last, false);
   3801         }
   3802 
   3803         // Insert the group back into mRecentTasks at start.
   3804         mRecentTasks.addAll(start, mTmpRecents);
   3805 
   3806         // Let the caller know where we left off.
   3807         return start + tmpSize;
   3808     }
   3809 
   3810     /**
   3811      * Update the recent tasks lists: make sure tasks should still be here (their
   3812      * applications / activities still exist), update their availability, fixup ordering
   3813      * of affiliations.
   3814      */
   3815     void cleanupRecentTasksLocked(int userId) {
   3816         if (mRecentTasks == null) {
   3817             // Happens when called from the packagemanager broadcast before boot.
   3818             return;
   3819         }
   3820 
   3821         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
   3822         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
   3823         final IPackageManager pm = AppGlobals.getPackageManager();
   3824         final ActivityInfo dummyAct = new ActivityInfo();
   3825         final ApplicationInfo dummyApp = new ApplicationInfo();
   3826 
   3827         int N = mRecentTasks.size();
   3828 
   3829         int[] users = userId == UserHandle.USER_ALL
   3830                 ? getUsersLocked() : new int[] { userId };
   3831         for (int user : users) {
   3832             for (int i = 0; i < N; i++) {
   3833                 TaskRecord task = mRecentTasks.get(i);
   3834                 if (task.userId != user) {
   3835                     // Only look at tasks for the user ID of interest.
   3836                     continue;
   3837                 }
   3838                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
   3839                     // This situation is broken, and we should just get rid of it now.
   3840                     mRecentTasks.remove(i);
   3841                     task.removedFromRecents();
   3842                     i--;
   3843                     N--;
   3844                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
   3845                     continue;
   3846                 }
   3847                 // Check whether this activity is currently available.
   3848                 if (task.realActivity != null) {
   3849                     ActivityInfo ai = availActCache.get(task.realActivity);
   3850                     if (ai == null) {
   3851                         try {
   3852                             ai = pm.getActivityInfo(task.realActivity,
   3853                                     PackageManager.GET_UNINSTALLED_PACKAGES
   3854                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
   3855                         } catch (RemoteException e) {
   3856                             // Will never happen.
   3857                             continue;
   3858                         }
   3859                         if (ai == null) {
   3860                             ai = dummyAct;
   3861                         }
   3862                         availActCache.put(task.realActivity, ai);
   3863                     }
   3864                     if (ai == dummyAct) {
   3865                         // This could be either because the activity no longer exists, or the
   3866                         // app is temporarily gone.  For the former we want to remove the recents
   3867                         // entry; for the latter we want to mark it as unavailable.
   3868                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
   3869                         if (app == null) {
   3870                             try {
   3871                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
   3872                                         PackageManager.GET_UNINSTALLED_PACKAGES
   3873                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
   3874                             } catch (RemoteException e) {
   3875                                 // Will never happen.
   3876                                 continue;
   3877                             }
   3878                             if (app == null) {
   3879                                 app = dummyApp;
   3880                             }
   3881                             availAppCache.put(task.realActivity.getPackageName(), app);
   3882                         }
   3883                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   3884                             // Doesn't exist any more!  Good-bye.
   3885                             mRecentTasks.remove(i);
   3886                             task.removedFromRecents();
   3887                             i--;
   3888                             N--;
   3889                             Slog.w(TAG, "Removing no longer valid recent: " + task);
   3890                             continue;
   3891                         } else {
   3892                             // Otherwise just not available for now.
   3893                             if (task.isAvailable) {
   3894                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   3895                                         + task);
   3896                             }
   3897                             task.isAvailable = false;
   3898                         }
   3899                     } else {
   3900                         if (!ai.enabled || !ai.applicationInfo.enabled
   3901                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   3902                             if (task.isAvailable) {
   3903                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   3904                                         + task + " (enabled=" + ai.enabled + "/"
   3905                                         + ai.applicationInfo.enabled +  " flags="
   3906                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
   3907                             }
   3908                             task.isAvailable = false;
   3909                         } else {
   3910                             if (!task.isAvailable) {
   3911                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
   3912                                         + task);
   3913                             }
   3914                             task.isAvailable = true;
   3915                         }
   3916                     }
   3917                 }
   3918             }
   3919         }
   3920 
   3921         // Verify the affiliate chain for each task.
   3922         for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
   3923         }
   3924 
   3925         mTmpRecents.clear();
   3926         // mRecentTasks is now in sorted, affiliated order.
   3927     }
   3928 
   3929     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
   3930         int N = mRecentTasks.size();
   3931         TaskRecord top = task;
   3932         int topIndex = taskIndex;
   3933         while (top.mNextAffiliate != null && topIndex > 0) {
   3934             top = top.mNextAffiliate;
   3935             topIndex--;
   3936         }
   3937         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
   3938                 + topIndex + " from intial " + taskIndex);
   3939         // Find the end of the chain, doing a sanity check along the way.
   3940         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
   3941         int endIndex = topIndex;
   3942         TaskRecord prev = top;
   3943         while (endIndex < N) {
   3944             TaskRecord cur = mRecentTasks.get(endIndex);
   3945             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
   3946                     + endIndex + " " + cur);
   3947             if (cur == top) {
   3948                 // Verify start of the chain.
   3949                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
   3950                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3951                             + ": first task has next affiliate: " + prev);
   3952                     sane = false;
   3953                     break;
   3954                 }
   3955             } else {
   3956                 // Verify middle of the chain's next points back to the one before.
   3957                 if (cur.mNextAffiliate != prev
   3958                         || cur.mNextAffiliateTaskId != prev.taskId) {
   3959                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3960                             + ": middle task " + cur + " @" + endIndex
   3961                             + " has bad next affiliate "
   3962                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
   3963                             + ", expected " + prev);
   3964                     sane = false;
   3965                     break;
   3966                 }
   3967             }
   3968             if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
   3969                 // Chain ends here.
   3970                 if (cur.mPrevAffiliate != null) {
   3971                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3972                             + ": last task " + cur + " has previous affiliate "
   3973                             + cur.mPrevAffiliate);
   3974                     sane = false;
   3975                 }
   3976                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
   3977                 break;
   3978             } else {
   3979                 // Verify middle of the chain's prev points to a valid item.
   3980                 if (cur.mPrevAffiliate == null) {
   3981                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3982                             + ": task " + cur + " has previous affiliate "
   3983                             + cur.mPrevAffiliate + " but should be id "
   3984                             + cur.mPrevAffiliate);
   3985                     sane = false;
   3986                     break;
   3987                 }
   3988             }
   3989             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
   3990                 Slog.wtf(TAG, "Bad chain @" + endIndex
   3991                         + ": task " + cur + " has affiliated id "
   3992                         + cur.mAffiliatedTaskId + " but should be "
   3993                         + task.mAffiliatedTaskId);
   3994                 sane = false;
   3995                 break;
   3996             }
   3997             prev = cur;
   3998             endIndex++;
   3999             if (endIndex >= N) {
   4000                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
   4001                         + ": last task " + prev);
   4002                 sane = false;
   4003                 break;
   4004             }
   4005         }
   4006         if (sane) {
   4007             if (endIndex < taskIndex) {
   4008                 Slog.wtf(TAG, "Bad chain @" + endIndex
   4009                         + ": did not extend to task " + task + " @" + taskIndex);
   4010                 sane = false;
   4011             }
   4012         }
   4013         if (sane) {
   4014             // All looks good, we can just move all of the affiliated tasks
   4015             // to the top.
   4016             for (int i=topIndex; i<=endIndex; i++) {
   4017                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
   4018                         + " from " + i + " to " + (i-topIndex));
   4019                 TaskRecord cur = mRecentTasks.remove(i);
   4020                 mRecentTasks.add(i-topIndex, cur);
   4021             }
   4022             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
   4023                     + " to " + endIndex);
   4024             return true;
   4025         }
   4026 
   4027         // Whoops, couldn't do it.
   4028         return false;
   4029     }
   4030 
   4031     final void addRecentTaskLocked(TaskRecord task) {
   4032         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
   4033                 || task.mNextAffiliateTaskId != INVALID_TASK_ID
   4034                 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
   4035 
   4036         int N = mRecentTasks.size();
   4037         // Quick case: check if the top-most recent task is the same.
   4038         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
   4039             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
   4040             return;
   4041         }
   4042         // Another quick case: check if this is part of a set of affiliated
   4043         // tasks that are at the top.
   4044         if (isAffiliated && N > 0 && task.inRecents
   4045                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
   4046             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
   4047                     + " at top when adding " + task);
   4048             return;
   4049         }
   4050         // Another quick case: never add voice sessions.
   4051         if (task.voiceSession != null) {
   4052             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
   4053             return;
   4054         }
   4055 
   4056         boolean needAffiliationFix = false;
   4057 
   4058         // Slightly less quick case: the task is already in recents, so all we need
   4059         // to do is move it.
   4060         if (task.inRecents) {
   4061             int taskIndex = mRecentTasks.indexOf(task);
   4062             if (taskIndex >= 0) {
   4063                 if (!isAffiliated) {
   4064                     // Simple case: this is not an affiliated task, so we just move it to the front.
   4065                     mRecentTasks.remove(taskIndex);
   4066                     mRecentTasks.add(0, task);
   4067                     notifyTaskPersisterLocked(task, false);
   4068                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
   4069                             + " from " + taskIndex);
   4070                     return;
   4071                 } else {
   4072                     // More complicated: need to keep all affiliated tasks together.
   4073                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4074                         // All went well.
   4075                         return;
   4076                     }
   4077 
   4078                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4079                     // everything and then go through our general path of adding a new task.
   4080                     needAffiliationFix = true;
   4081                 }
   4082             } else {
   4083                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
   4084                 needAffiliationFix = true;
   4085             }
   4086         }
   4087 
   4088         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
   4089         trimRecentsForTaskLocked(task, true);
   4090 
   4091         N = mRecentTasks.size();
   4092         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
   4093             final TaskRecord tr = mRecentTasks.remove(N - 1);
   4094             tr.removedFromRecents();
   4095             N--;
   4096         }
   4097         task.inRecents = true;
   4098         if (!isAffiliated || needAffiliationFix) {
   4099             // If this is a simple non-affiliated task, or we had some failure trying to
   4100             // handle it as part of an affilated task, then just place it at the top.
   4101             mRecentTasks.add(0, task);
   4102         } else if (isAffiliated) {
   4103             // If this is a new affiliated task, then move all of the affiliated tasks
   4104             // to the front and insert this new one.
   4105             TaskRecord other = task.mNextAffiliate;
   4106             if (other == null) {
   4107                 other = task.mPrevAffiliate;
   4108             }
   4109             if (other != null) {
   4110                 int otherIndex = mRecentTasks.indexOf(other);
   4111                 if (otherIndex >= 0) {
   4112                     // Insert new task at appropriate location.
   4113                     int taskIndex;
   4114                     if (other == task.mNextAffiliate) {
   4115                         // We found the index of our next affiliation, which is who is
   4116                         // before us in the list, so add after that point.
   4117                         taskIndex = otherIndex+1;
   4118                     } else {
   4119                         // We found the index of our previous affiliation, which is who is
   4120                         // after us in the list, so add at their position.
   4121                         taskIndex = otherIndex;
   4122                     }
   4123                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
   4124                             + taskIndex + ": " + task);
   4125                     mRecentTasks.add(taskIndex, task);
   4126 
   4127                     // Now move everything to the front.
   4128                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4129                         // All went well.
   4130                         return;
   4131                     }
   4132 
   4133                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4134                     // everything and then go through our general path of adding a new task.
   4135                     needAffiliationFix = true;
   4136                 } else {
   4137                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
   4138                             + other);
   4139                     needAffiliationFix = true;
   4140                 }
   4141             } else {
   4142                 if (DEBUG_RECENTS) Slog.d(TAG,
   4143                         "addRecent: adding affiliated task without next/prev:" + task);
   4144                 needAffiliationFix = true;
   4145             }
   4146         }
   4147         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
   4148 
   4149         if (needAffiliationFix) {
   4150             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
   4151             cleanupRecentTasksLocked(task.userId);
   4152         }
   4153     }
   4154 
   4155     /**
   4156      * If needed, remove oldest existing entries in recents that are for the same kind
   4157      * of task as the given one.
   4158      */
   4159     int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
   4160         int N = mRecentTasks.size();
   4161         final Intent intent = task.intent;
   4162         final boolean document = intent != null && intent.isDocument();
   4163 
   4164         int maxRecents = task.maxRecents - 1;
   4165         for (int i=0; i<N; i++) {
   4166             final TaskRecord tr = mRecentTasks.get(i);
   4167             if (task != tr) {
   4168                 if (task.userId != tr.userId) {
   4169                     continue;
   4170                 }
   4171                 if (i > MAX_RECENT_BITMAPS) {
   4172                     tr.freeLastThumbnail();
   4173                 }
   4174                 final Intent trIntent = tr.intent;
   4175                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
   4176                     (intent == null || !intent.filterEquals(trIntent))) {
   4177                     continue;
   4178                 }
   4179                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
   4180                 if (document && trIsDocument) {
   4181                     // These are the same document activity (not necessarily the same doc).
   4182                     if (maxRecents > 0) {
   4183                         --maxRecents;
   4184                         continue;
   4185                     }
   4186                     // Hit the maximum number of documents for this task. Fall through
   4187                     // and remove this document from recents.
   4188                 } else if (document || trIsDocument) {
   4189                     // Only one of these is a document. Not the droid we're looking for.
   4190                     continue;
   4191                 }
   4192             }
   4193 
   4194             if (!doTrim) {
   4195                 // If the caller is not actually asking for a trim, just tell them we reached
   4196                 // a point where the trim would happen.
   4197                 return i;
   4198             }
   4199 
   4200             // Either task and tr are the same or, their affinities match or their intents match
   4201             // and neither of them is a document, or they are documents using the same activity
   4202             // and their maxRecents has been reached.
   4203             tr.disposeThumbnail();
   4204             mRecentTasks.remove(i);
   4205             if (task != tr) {
   4206                 tr.removedFromRecents();
   4207             }
   4208             i--;
   4209             N--;
   4210             if (task.intent == null) {
   4211                 // If the new recent task we are adding is not fully
   4212                 // specified, then replace it with the existing recent task.
   4213                 task = tr;
   4214             }
   4215             notifyTaskPersisterLocked(tr, false);
   4216         }
   4217 
   4218         return -1;
   4219     }
   4220 
   4221     @Override
   4222     public void reportActivityFullyDrawn(IBinder token) {
   4223         synchronized (this) {
   4224             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4225             if (r == null) {
   4226                 return;
   4227             }
   4228             r.reportFullyDrawnLocked();
   4229         }
   4230     }
   4231 
   4232     @Override
   4233     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4234         synchronized (this) {
   4235             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4236             if (r == null) {
   4237                 return;
   4238             }
   4239             final long origId = Binder.clearCallingIdentity();
   4240             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4241             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4242                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4243             if (config != null) {
   4244                 r.frozenBeforeDestroy = true;
   4245                 if (!updateConfigurationLocked(config, r, false, false)) {
   4246                     mStackSupervisor.resumeTopActivitiesLocked();
   4247                 }
   4248             }
   4249             Binder.restoreCallingIdentity(origId);
   4250         }
   4251     }
   4252 
   4253     @Override
   4254     public int getRequestedOrientation(IBinder token) {
   4255         synchronized (this) {
   4256             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4257             if (r == null) {
   4258                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4259             }
   4260             return mWindowManager.getAppOrientation(r.appToken);
   4261         }
   4262     }
   4263 
   4264     /**
   4265      * This is the internal entry point for handling Activity.finish().
   4266      *
   4267      * @param token The Binder token referencing the Activity we want to finish.
   4268      * @param resultCode Result code, if any, from this Activity.
   4269      * @param resultData Result data (Intent), if any, from this Activity.
   4270      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
   4271      *            the root Activity in the task.
   4272      *
   4273      * @return Returns true if the activity successfully finished, or false if it is still running.
   4274      */
   4275     @Override
   4276     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4277             boolean finishTask) {
   4278         // Refuse possible leaked file descriptors
   4279         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4280             throw new IllegalArgumentException("File descriptors passed in Intent");
   4281         }
   4282 
   4283         synchronized(this) {
   4284             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4285             if (r == null) {
   4286                 return true;
   4287             }
   4288             // Keep track of the root activity of the task before we finish it
   4289             TaskRecord tr = r.task;
   4290             ActivityRecord rootR = tr.getRootActivity();
   4291             if (rootR == null) {
   4292                 Slog.w(TAG, "Finishing task with all activities already finished");
   4293             }
   4294             // Do not allow task to finish in Lock Task mode.
   4295             if (tr == mStackSupervisor.mLockTaskModeTask) {
   4296                 if (rootR == r) {
   4297                     Slog.i(TAG, "Not finishing task in lock task mode");
   4298                     mStackSupervisor.showLockTaskToast();
   4299                     return false;
   4300                 }
   4301             }
   4302             if (mController != null) {
   4303                 // Find the first activity that is not finishing.
   4304                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4305                 if (next != null) {
   4306                     // ask watcher if this is allowed
   4307                     boolean resumeOK = true;
   4308                     try {
   4309                         resumeOK = mController.activityResuming(next.packageName);
   4310                     } catch (RemoteException e) {
   4311                         mController = null;
   4312                         Watchdog.getInstance().setActivityController(null);
   4313                     }
   4314 
   4315                     if (!resumeOK) {
   4316                         Slog.i(TAG, "Not finishing activity because controller resumed");
   4317                         return false;
   4318                     }
   4319                 }
   4320             }
   4321             final long origId = Binder.clearCallingIdentity();
   4322             try {
   4323                 boolean res;
   4324                 if (finishTask && r == rootR) {
   4325                     // If requested, remove the task that is associated to this activity only if it
   4326                     // was the root activity in the task. The result code and data is ignored
   4327                     // because we don't support returning them across task boundaries.
   4328                     res = removeTaskByIdLocked(tr.taskId, false);
   4329                     if (!res) {
   4330                         Slog.i(TAG, "Removing task failed to finish activity");
   4331                     }
   4332                 } else {
   4333                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4334                             resultData, "app-request", true);
   4335                     if (!res) {
   4336                         Slog.i(TAG, "Failed to finish by app-request");
   4337                     }
   4338                 }
   4339                 return res;
   4340             } finally {
   4341                 Binder.restoreCallingIdentity(origId);
   4342             }
   4343         }
   4344     }
   4345 
   4346     @Override
   4347     public final void finishHeavyWeightApp() {
   4348         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4349                 != PackageManager.PERMISSION_GRANTED) {
   4350             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4351                     + Binder.getCallingPid()
   4352                     + ", uid=" + Binder.getCallingUid()
   4353                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4354             Slog.w(TAG, msg);
   4355             throw new SecurityException(msg);
   4356         }
   4357 
   4358         synchronized(this) {
   4359             if (mHeavyWeightProcess == null) {
   4360                 return;
   4361             }
   4362 
   4363             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   4364                     mHeavyWeightProcess.activities);
   4365             for (int i=0; i<activities.size(); i++) {
   4366                 ActivityRecord r = activities.get(i);
   4367                 if (!r.finishing) {
   4368                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4369                             null, "finish-heavy", true);
   4370                 }
   4371             }
   4372 
   4373             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4374                     mHeavyWeightProcess.userId, 0));
   4375             mHeavyWeightProcess = null;
   4376         }
   4377     }
   4378 
   4379     @Override
   4380     public void crashApplication(int uid, int initialPid, String packageName,
   4381             String message) {
   4382         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4383                 != PackageManager.PERMISSION_GRANTED) {
   4384             String msg = "Permission Denial: crashApplication() from pid="
   4385                     + Binder.getCallingPid()
   4386                     + ", uid=" + Binder.getCallingUid()
   4387                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4388             Slog.w(TAG, msg);
   4389             throw new SecurityException(msg);
   4390         }
   4391 
   4392         synchronized(this) {
   4393             ProcessRecord proc = null;
   4394 
   4395             // Figure out which process to kill.  We don't trust that initialPid
   4396             // still has any relation to current pids, so must scan through the
   4397             // list.
   4398             synchronized (mPidsSelfLocked) {
   4399                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   4400                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   4401                     if (p.uid != uid) {
   4402                         continue;
   4403                     }
   4404                     if (p.pid == initialPid) {
   4405                         proc = p;
   4406                         break;
   4407                     }
   4408                     if (p.pkgList.containsKey(packageName)) {
   4409                         proc = p;
   4410                     }
   4411                 }
   4412             }
   4413 
   4414             if (proc == null) {
   4415                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   4416                         + " initialPid=" + initialPid
   4417                         + " packageName=" + packageName);
   4418                 return;
   4419             }
   4420 
   4421             if (proc.thread != null) {
   4422                 if (proc.pid == Process.myPid()) {
   4423                     Log.w(TAG, "crashApplication: trying to crash self!");
   4424                     return;
   4425                 }
   4426                 long ident = Binder.clearCallingIdentity();
   4427                 try {
   4428                     proc.thread.scheduleCrash(message);
   4429                 } catch (RemoteException e) {
   4430                 }
   4431                 Binder.restoreCallingIdentity(ident);
   4432             }
   4433         }
   4434     }
   4435 
   4436     @Override
   4437     public final void finishSubActivity(IBinder token, String resultWho,
   4438             int requestCode) {
   4439         synchronized(this) {
   4440             final long origId = Binder.clearCallingIdentity();
   4441             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4442             if (r != null) {
   4443                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4444             }
   4445             Binder.restoreCallingIdentity(origId);
   4446         }
   4447     }
   4448 
   4449     @Override
   4450     public boolean finishActivityAffinity(IBinder token) {
   4451         synchronized(this) {
   4452             final long origId = Binder.clearCallingIdentity();
   4453             try {
   4454                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4455 
   4456                 ActivityRecord rootR = r.task.getRootActivity();
   4457                 // Do not allow task to finish in Lock Task mode.
   4458                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
   4459                     if (rootR == r) {
   4460                         mStackSupervisor.showLockTaskToast();
   4461                         return false;
   4462                     }
   4463                 }
   4464                 boolean res = false;
   4465                 if (r != null) {
   4466                     res = r.task.stack.finishActivityAffinityLocked(r);
   4467                 }
   4468                 return res;
   4469             } finally {
   4470                 Binder.restoreCallingIdentity(origId);
   4471             }
   4472         }
   4473     }
   4474 
   4475     @Override
   4476     public void finishVoiceTask(IVoiceInteractionSession session) {
   4477         synchronized(this) {
   4478             final long origId = Binder.clearCallingIdentity();
   4479             try {
   4480                 mStackSupervisor.finishVoiceTask(session);
   4481             } finally {
   4482                 Binder.restoreCallingIdentity(origId);
   4483             }
   4484         }
   4485 
   4486     }
   4487 
   4488     @Override
   4489     public boolean releaseActivityInstance(IBinder token) {
   4490         synchronized(this) {
   4491             final long origId = Binder.clearCallingIdentity();
   4492             try {
   4493                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4494                 if (r.task == null || r.task.stack == null) {
   4495                     return false;
   4496                 }
   4497                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   4498             } finally {
   4499                 Binder.restoreCallingIdentity(origId);
   4500             }
   4501         }
   4502     }
   4503 
   4504     @Override
   4505     public void releaseSomeActivities(IApplicationThread appInt) {
   4506         synchronized(this) {
   4507             final long origId = Binder.clearCallingIdentity();
   4508             try {
   4509                 ProcessRecord app = getRecordForAppLocked(appInt);
   4510                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   4511             } finally {
   4512                 Binder.restoreCallingIdentity(origId);
   4513             }
   4514         }
   4515     }
   4516 
   4517     @Override
   4518     public boolean willActivityBeVisible(IBinder token) {
   4519         synchronized(this) {
   4520             ActivityStack stack = ActivityRecord.getStackLocked(token);
   4521             if (stack != null) {
   4522                 return stack.willActivityBeVisibleLocked(token);
   4523             }
   4524             return false;
   4525         }
   4526     }
   4527 
   4528     @Override
   4529     public void overridePendingTransition(IBinder token, String packageName,
   4530             int enterAnim, int exitAnim) {
   4531         synchronized(this) {
   4532             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   4533             if (self == null) {
   4534                 return;
   4535             }
   4536 
   4537             final long origId = Binder.clearCallingIdentity();
   4538 
   4539             if (self.state == ActivityState.RESUMED
   4540                     || self.state == ActivityState.PAUSING) {
   4541                 mWindowManager.overridePendingAppTransition(packageName,
   4542                         enterAnim, exitAnim, null);
   4543             }
   4544 
   4545             Binder.restoreCallingIdentity(origId);
   4546         }
   4547     }
   4548 
   4549     /**
   4550      * Main function for removing an existing process from the activity manager
   4551      * as a result of that process going away.  Clears out all connections
   4552      * to the process.
   4553      */
   4554     private final void handleAppDiedLocked(ProcessRecord app,
   4555             boolean restarting, boolean allowRestart) {
   4556         int pid = app.pid;
   4557         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   4558         if (!kept && !restarting) {
   4559             removeLruProcessLocked(app);
   4560             if (pid > 0) {
   4561                 ProcessList.remove(pid);
   4562             }
   4563         }
   4564 
   4565         if (mProfileProc == app) {
   4566             clearProfilerLocked();
   4567         }
   4568 
   4569         // Remove this application's activities from active lists.
   4570         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   4571 
   4572         app.activities.clear();
   4573 
   4574         if (app.instrumentationClass != null) {
   4575             Slog.w(TAG, "Crash of app " + app.processName
   4576                   + " running instrumentation " + app.instrumentationClass);
   4577             Bundle info = new Bundle();
   4578             info.putString("shortMsg", "Process crashed.");
   4579             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   4580         }
   4581 
   4582         if (!restarting) {
   4583             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
   4584                 // If there was nothing to resume, and we are not already
   4585                 // restarting this process, but there is a visible activity that
   4586                 // is hosted by the process...  then make sure all visible
   4587                 // activities are running, taking care of restarting this
   4588                 // process.
   4589                 if (hasVisibleActivities) {
   4590                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   4591                 }
   4592             }
   4593         }
   4594     }
   4595 
   4596     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   4597         IBinder threadBinder = thread.asBinder();
   4598         // Find the application record.
   4599         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4600             ProcessRecord rec = mLruProcesses.get(i);
   4601             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   4602                 return i;
   4603             }
   4604         }
   4605         return -1;
   4606     }
   4607 
   4608     final ProcessRecord getRecordForAppLocked(
   4609             IApplicationThread thread) {
   4610         if (thread == null) {
   4611             return null;
   4612         }
   4613 
   4614         int appIndex = getLRURecordIndexForAppLocked(thread);
   4615         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   4616     }
   4617 
   4618     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   4619         // If there are no longer any background processes running,
   4620         // and the app that died was not running instrumentation,
   4621         // then tell everyone we are now low on memory.
   4622         boolean haveBg = false;
   4623         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4624             ProcessRecord rec = mLruProcesses.get(i);
   4625             if (rec.thread != null
   4626                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   4627                 haveBg = true;
   4628                 break;
   4629             }
   4630         }
   4631 
   4632         if (!haveBg) {
   4633             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   4634             if (doReport) {
   4635                 long now = SystemClock.uptimeMillis();
   4636                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   4637                     doReport = false;
   4638                 } else {
   4639                     mLastMemUsageReportTime = now;
   4640                 }
   4641             }
   4642             final ArrayList<ProcessMemInfo> memInfos
   4643                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   4644             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   4645             long now = SystemClock.uptimeMillis();
   4646             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4647                 ProcessRecord rec = mLruProcesses.get(i);
   4648                 if (rec == dyingProc || rec.thread == null) {
   4649                     continue;
   4650                 }
   4651                 if (doReport) {
   4652                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   4653                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   4654                 }
   4655                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   4656                     // The low memory report is overriding any current
   4657                     // state for a GC request.  Make sure to do
   4658                     // heavy/important/visible/foreground processes first.
   4659                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   4660                         rec.lastRequestedGc = 0;
   4661                     } else {
   4662                         rec.lastRequestedGc = rec.lastLowMemory;
   4663                     }
   4664                     rec.reportLowMemory = true;
   4665                     rec.lastLowMemory = now;
   4666                     mProcessesToGc.remove(rec);
   4667                     addProcessToGcListLocked(rec);
   4668                 }
   4669             }
   4670             if (doReport) {
   4671                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   4672                 mHandler.sendMessage(msg);
   4673             }
   4674             scheduleAppGcsLocked();
   4675         }
   4676     }
   4677 
   4678     final void appDiedLocked(ProcessRecord app) {
   4679        appDiedLocked(app, app.pid, app.thread);
   4680     }
   4681 
   4682     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
   4683         // First check if this ProcessRecord is actually active for the pid.
   4684         synchronized (mPidsSelfLocked) {
   4685             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   4686             if (curProc != app) {
   4687                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   4688                 return;
   4689             }
   4690         }
   4691 
   4692         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   4693         synchronized (stats) {
   4694             stats.noteProcessDiedLocked(app.info.uid, pid);
   4695         }
   4696 
   4697         if (!app.killed) {
   4698             Process.killProcessQuiet(pid);
   4699             Process.killProcessGroup(app.info.uid, pid);
   4700             app.killed = true;
   4701         }
   4702 
   4703         // Clean up already done if the process has been re-started.
   4704         if (app.pid == pid && app.thread != null &&
   4705                 app.thread.asBinder() == thread.asBinder()) {
   4706             boolean doLowMem = app.instrumentationClass == null;
   4707             boolean doOomAdj = doLowMem;
   4708             if (!app.killedByAm) {
   4709                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4710                         + ") has died");
   4711                 mAllowLowerMemLevel = true;
   4712             } else {
   4713                 // Note that we always want to do oom adj to update our state with the
   4714                 // new number of procs.
   4715                 mAllowLowerMemLevel = false;
   4716                 doLowMem = false;
   4717             }
   4718             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4719             if (DEBUG_CLEANUP) Slog.v(
   4720                 TAG, "Dying app: " + app + ", pid: " + pid
   4721                 + ", thread: " + thread.asBinder());
   4722             handleAppDiedLocked(app, false, true);
   4723 
   4724             if (doOomAdj) {
   4725                 updateOomAdjLocked();
   4726             }
   4727             if (doLowMem) {
   4728                 doLowMemReportIfNeededLocked(app);
   4729             }
   4730         } else if (app.pid != pid) {
   4731             // A new process has already been started.
   4732             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4733                     + ") has died and restarted (pid " + app.pid + ").");
   4734             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4735         } else if (DEBUG_PROCESSES) {
   4736             Slog.d(TAG, "Received spurious death notification for thread "
   4737                     + thread.asBinder());
   4738         }
   4739     }
   4740 
   4741     /**
   4742      * If a stack trace dump file is configured, dump process stack traces.
   4743      * @param clearTraces causes the dump file to be erased prior to the new
   4744      *    traces being written, if true; when false, the new traces will be
   4745      *    appended to any existing file content.
   4746      * @param firstPids of dalvik VM processes to dump stack traces for first
   4747      * @param lastPids of dalvik VM processes to dump stack traces for last
   4748      * @param nativeProcs optional list of native process names to dump stack crawls
   4749      * @return file containing stack traces, or null if no dump file is configured
   4750      */
   4751     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   4752             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4753         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4754         if (tracesPath == null || tracesPath.length() == 0) {
   4755             return null;
   4756         }
   4757 
   4758         File tracesFile = new File(tracesPath);
   4759         try {
   4760             File tracesDir = tracesFile.getParentFile();
   4761             if (!tracesDir.exists()) {
   4762                 tracesDir.mkdirs();
   4763                 if (!SELinux.restorecon(tracesDir)) {
   4764                     return null;
   4765                 }
   4766             }
   4767             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4768 
   4769             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   4770             tracesFile.createNewFile();
   4771             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4772         } catch (IOException e) {
   4773             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   4774             return null;
   4775         }
   4776 
   4777         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   4778         return tracesFile;
   4779     }
   4780 
   4781     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   4782             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4783         // Use a FileObserver to detect when traces finish writing.
   4784         // The order of traces is considered important to maintain for legibility.
   4785         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   4786             @Override
   4787             public synchronized void onEvent(int event, String path) { notify(); }
   4788         };
   4789 
   4790         try {
   4791             observer.startWatching();
   4792 
   4793             // First collect all of the stacks of the most important pids.
   4794             if (firstPids != null) {
   4795                 try {
   4796                     int num = firstPids.size();
   4797                     for (int i = 0; i < num; i++) {
   4798                         synchronized (observer) {
   4799                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   4800                             observer.wait(200);  // Wait for write-close, give up after 200msec
   4801                         }
   4802                     }
   4803                 } catch (InterruptedException e) {
   4804                     Slog.wtf(TAG, e);
   4805                 }
   4806             }
   4807 
   4808             // Next collect the stacks of the native pids
   4809             if (nativeProcs != null) {
   4810                 int[] pids = Process.getPidsForCommands(nativeProcs);
   4811                 if (pids != null) {
   4812                     for (int pid : pids) {
   4813                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   4814                     }
   4815                 }
   4816             }
   4817 
   4818             // Lastly, measure CPU usage.
   4819             if (processCpuTracker != null) {
   4820                 processCpuTracker.init();
   4821                 System.gc();
   4822                 processCpuTracker.update();
   4823                 try {
   4824                     synchronized (processCpuTracker) {
   4825                         processCpuTracker.wait(500); // measure over 1/2 second.
   4826                     }
   4827                 } catch (InterruptedException e) {
   4828                 }
   4829                 processCpuTracker.update();
   4830 
   4831                 // We'll take the stack crawls of just the top apps using CPU.
   4832                 final int N = processCpuTracker.countWorkingStats();
   4833                 int numProcs = 0;
   4834                 for (int i=0; i<N && numProcs<5; i++) {
   4835                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   4836                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   4837                         numProcs++;
   4838                         try {
   4839                             synchronized (observer) {
   4840                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   4841                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   4842                             }
   4843                         } catch (InterruptedException e) {
   4844                             Slog.wtf(TAG, e);
   4845                         }
   4846 
   4847                     }
   4848                 }
   4849             }
   4850         } finally {
   4851             observer.stopWatching();
   4852         }
   4853     }
   4854 
   4855     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   4856         if (true || IS_USER_BUILD) {
   4857             return;
   4858         }
   4859         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4860         if (tracesPath == null || tracesPath.length() == 0) {
   4861             return;
   4862         }
   4863 
   4864         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   4865         StrictMode.allowThreadDiskWrites();
   4866         try {
   4867             final File tracesFile = new File(tracesPath);
   4868             final File tracesDir = tracesFile.getParentFile();
   4869             final File tracesTmp = new File(tracesDir, "__tmp__");
   4870             try {
   4871                 if (!tracesDir.exists()) {
   4872                     tracesDir.mkdirs();
   4873                     if (!SELinux.restorecon(tracesDir.getPath())) {
   4874                         return;
   4875                     }
   4876                 }
   4877                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4878 
   4879                 if (tracesFile.exists()) {
   4880                     tracesTmp.delete();
   4881                     tracesFile.renameTo(tracesTmp);
   4882                 }
   4883                 StringBuilder sb = new StringBuilder();
   4884                 Time tobj = new Time();
   4885                 tobj.set(System.currentTimeMillis());
   4886                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   4887                 sb.append(": ");
   4888                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   4889                 sb.append(" since ");
   4890                 sb.append(msg);
   4891                 FileOutputStream fos = new FileOutputStream(tracesFile);
   4892                 fos.write(sb.toString().getBytes());
   4893                 if (app == null) {
   4894                     fos.write("\n*** No application process!".getBytes());
   4895                 }
   4896                 fos.close();
   4897                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4898             } catch (IOException e) {
   4899                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   4900                 return;
   4901             }
   4902 
   4903             if (app != null) {
   4904                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   4905                 firstPids.add(app.pid);
   4906                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   4907             }
   4908 
   4909             File lastTracesFile = null;
   4910             File curTracesFile = null;
   4911             for (int i=9; i>=0; i--) {
   4912                 String name = String.format(Locale.US, "slow%02d.txt", i);
   4913                 curTracesFile = new File(tracesDir, name);
   4914                 if (curTracesFile.exists()) {
   4915                     if (lastTracesFile != null) {
   4916                         curTracesFile.renameTo(lastTracesFile);
   4917                     } else {
   4918                         curTracesFile.delete();
   4919                     }
   4920                 }
   4921                 lastTracesFile = curTracesFile;
   4922             }
   4923             tracesFile.renameTo(curTracesFile);
   4924             if (tracesTmp.exists()) {
   4925                 tracesTmp.renameTo(tracesFile);
   4926             }
   4927         } finally {
   4928             StrictMode.setThreadPolicy(oldPolicy);
   4929         }
   4930     }
   4931 
   4932     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   4933             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   4934         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   4935         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   4936 
   4937         if (mController != null) {
   4938             try {
   4939                 // 0 == continue, -1 = kill process immediately
   4940                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   4941                 if (res < 0 && app.pid != MY_PID) {
   4942                     app.kill("anr", true);
   4943                 }
   4944             } catch (RemoteException e) {
   4945                 mController = null;
   4946                 Watchdog.getInstance().setActivityController(null);
   4947             }
   4948         }
   4949 
   4950         long anrTime = SystemClock.uptimeMillis();
   4951         if (MONITOR_CPU_USAGE) {
   4952             updateCpuStatsNow();
   4953         }
   4954 
   4955         synchronized (this) {
   4956             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   4957             if (mShuttingDown) {
   4958                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   4959                 return;
   4960             } else if (app.notResponding) {
   4961                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   4962                 return;
   4963             } else if (app.crashing) {
   4964                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   4965                 return;
   4966             }
   4967 
   4968             // In case we come through here for the same app before completing
   4969             // this one, mark as anring now so we will bail out.
   4970             app.notResponding = true;
   4971 
   4972             // Log the ANR to the event log.
   4973             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   4974                     app.processName, app.info.flags, annotation);
   4975 
   4976             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   4977             firstPids.add(app.pid);
   4978 
   4979             int parentPid = app.pid;
   4980             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   4981             if (parentPid != app.pid) firstPids.add(parentPid);
   4982 
   4983             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   4984 
   4985             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   4986                 ProcessRecord r = mLruProcesses.get(i);
   4987                 if (r != null && r.thread != null) {
   4988                     int pid = r.pid;
   4989                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   4990                         if (r.persistent) {
   4991                             firstPids.add(pid);
   4992                         } else {
   4993                             lastPids.put(pid, Boolean.TRUE);
   4994                         }
   4995                     }
   4996                 }
   4997             }
   4998         }
   4999 
   5000         // Log the ANR to the main log.
   5001         StringBuilder info = new StringBuilder();
   5002         info.setLength(0);
   5003         info.append("ANR in ").append(app.processName);
   5004         if (activity != null && activity.shortComponentName != null) {
   5005             info.append(" (").append(activity.shortComponentName).append(")");
   5006         }
   5007         info.append("\n");
   5008         info.append("PID: ").append(app.pid).append("\n");
   5009         if (annotation != null) {
   5010             info.append("Reason: ").append(annotation).append("\n");
   5011         }
   5012         if (parent != null && parent != activity) {
   5013             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   5014         }
   5015 
   5016         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
   5017 
   5018         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
   5019                 NATIVE_STACKS_OF_INTEREST);
   5020 
   5021         String cpuInfo = null;
   5022         if (MONITOR_CPU_USAGE) {
   5023             updateCpuStatsNow();
   5024             synchronized (mProcessCpuTracker) {
   5025                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
   5026             }
   5027             info.append(processCpuTracker.printCurrentLoad());
   5028             info.append(cpuInfo);
   5029         }
   5030 
   5031         info.append(processCpuTracker.printCurrentState(anrTime));
   5032 
   5033         Slog.e(TAG, info.toString());
   5034         if (tracesFile == null) {
   5035             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   5036             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   5037         }
   5038 
   5039         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   5040                 cpuInfo, tracesFile, null);
   5041 
   5042         if (mController != null) {
   5043             try {
   5044                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   5045                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   5046                 if (res != 0) {
   5047                     if (res < 0 && app.pid != MY_PID) {
   5048                         app.kill("anr", true);
   5049                     } else {
   5050                         synchronized (this) {
   5051                             mServices.scheduleServiceTimeoutLocked(app);
   5052                         }
   5053                     }
   5054                     return;
   5055                 }
   5056             } catch (RemoteException e) {
   5057                 mController = null;
   5058                 Watchdog.getInstance().setActivityController(null);
   5059             }
   5060         }
   5061 
   5062         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   5063         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   5064                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   5065 
   5066         synchronized (this) {
   5067             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
   5068 
   5069             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   5070                 app.kill("bg anr", true);
   5071                 return;
   5072             }
   5073 
   5074             // Set the app's notResponding state, and look up the errorReportReceiver
   5075             makeAppNotRespondingLocked(app,
   5076                     activity != null ? activity.shortComponentName : null,
   5077                     annotation != null ? "ANR " + annotation : "ANR",
   5078                     info.toString());
   5079 
   5080             // Bring up the infamous App Not Responding dialog
   5081             Message msg = Message.obtain();
   5082             HashMap<String, Object> map = new HashMap<String, Object>();
   5083             msg.what = SHOW_NOT_RESPONDING_MSG;
   5084             msg.obj = map;
   5085             msg.arg1 = aboveSystem ? 1 : 0;
   5086             map.put("app", app);
   5087             if (activity != null) {
   5088                 map.put("activity", activity);
   5089             }
   5090 
   5091             mHandler.sendMessage(msg);
   5092         }
   5093     }
   5094 
   5095     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5096         if (!mLaunchWarningShown) {
   5097             mLaunchWarningShown = true;
   5098             mHandler.post(new Runnable() {
   5099                 @Override
   5100                 public void run() {
   5101                     synchronized (ActivityManagerService.this) {
   5102                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5103                         d.show();
   5104                         mHandler.postDelayed(new Runnable() {
   5105                             @Override
   5106                             public void run() {
   5107                                 synchronized (ActivityManagerService.this) {
   5108                                     d.dismiss();
   5109                                     mLaunchWarningShown = false;
   5110                                 }
   5111                             }
   5112                         }, 4000);
   5113                     }
   5114                 }
   5115             });
   5116         }
   5117     }
   5118 
   5119     @Override
   5120     public boolean clearApplicationUserData(final String packageName,
   5121             final IPackageDataObserver observer, int userId) {
   5122         enforceNotIsolatedCaller("clearApplicationUserData");
   5123         int uid = Binder.getCallingUid();
   5124         int pid = Binder.getCallingPid();
   5125         userId = handleIncomingUser(pid, uid,
   5126                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5127         long callingId = Binder.clearCallingIdentity();
   5128         try {
   5129             IPackageManager pm = AppGlobals.getPackageManager();
   5130             int pkgUid = -1;
   5131             synchronized(this) {
   5132                 try {
   5133                     pkgUid = pm.getPackageUid(packageName, userId);
   5134                 } catch (RemoteException e) {
   5135                 }
   5136                 if (pkgUid == -1) {
   5137                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5138                     if (observer != null) {
   5139                         try {
   5140                             observer.onRemoveCompleted(packageName, false);
   5141                         } catch (RemoteException e) {
   5142                             Slog.i(TAG, "Observer no longer exists.");
   5143                         }
   5144                     }
   5145                     return false;
   5146                 }
   5147                 if (uid == pkgUid || checkComponentPermission(
   5148                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5149                         pid, uid, -1, true)
   5150                         == PackageManager.PERMISSION_GRANTED) {
   5151                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5152                 } else {
   5153                     throw new SecurityException("PID " + pid + " does not have permission "
   5154                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5155                                     + " of package " + packageName);
   5156                 }
   5157 
   5158                 // Remove all tasks match the cleared application package and user
   5159                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5160                     final TaskRecord tr = mRecentTasks.get(i);
   5161                     final String taskPackageName =
   5162                             tr.getBaseIntent().getComponent().getPackageName();
   5163                     if (tr.userId != userId) continue;
   5164                     if (!taskPackageName.equals(packageName)) continue;
   5165                     removeTaskByIdLocked(tr.taskId, false);
   5166                 }
   5167             }
   5168 
   5169             try {
   5170                 // Clear application user data
   5171                 pm.clearApplicationUserData(packageName, observer, userId);
   5172 
   5173                 synchronized(this) {
   5174                     // Remove all permissions granted from/to this package
   5175                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5176                 }
   5177 
   5178                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5179                         Uri.fromParts("package", packageName, null));
   5180                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   5181                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5182                         null, null, 0, null, null, null, false, false, userId);
   5183             } catch (RemoteException e) {
   5184             }
   5185         } finally {
   5186             Binder.restoreCallingIdentity(callingId);
   5187         }
   5188         return true;
   5189     }
   5190 
   5191     @Override
   5192     public void killBackgroundProcesses(final String packageName, int userId) {
   5193         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5194                 != PackageManager.PERMISSION_GRANTED &&
   5195                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5196                         != PackageManager.PERMISSION_GRANTED) {
   5197             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5198                     + Binder.getCallingPid()
   5199                     + ", uid=" + Binder.getCallingUid()
   5200                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5201             Slog.w(TAG, msg);
   5202             throw new SecurityException(msg);
   5203         }
   5204 
   5205         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5206                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5207         long callingId = Binder.clearCallingIdentity();
   5208         try {
   5209             IPackageManager pm = AppGlobals.getPackageManager();
   5210             synchronized(this) {
   5211                 int appId = -1;
   5212                 try {
   5213                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   5214                 } catch (RemoteException e) {
   5215                 }
   5216                 if (appId == -1) {
   5217                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5218                     return;
   5219                 }
   5220                 killPackageProcessesLocked(packageName, appId, userId,
   5221                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5222             }
   5223         } finally {
   5224             Binder.restoreCallingIdentity(callingId);
   5225         }
   5226     }
   5227 
   5228     @Override
   5229     public void killAllBackgroundProcesses() {
   5230         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5231                 != PackageManager.PERMISSION_GRANTED) {
   5232             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5233                     + Binder.getCallingPid()
   5234                     + ", uid=" + Binder.getCallingUid()
   5235                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5236             Slog.w(TAG, msg);
   5237             throw new SecurityException(msg);
   5238         }
   5239 
   5240         long callingId = Binder.clearCallingIdentity();
   5241         try {
   5242             synchronized(this) {
   5243                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5244                 final int NP = mProcessNames.getMap().size();
   5245                 for (int ip=0; ip<NP; ip++) {
   5246                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5247                     final int NA = apps.size();
   5248                     for (int ia=0; ia<NA; ia++) {
   5249                         ProcessRecord app = apps.valueAt(ia);
   5250                         if (app.persistent) {
   5251                             // we don't kill persistent processes
   5252                             continue;
   5253                         }
   5254                         if (app.removed) {
   5255                             procs.add(app);
   5256                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5257                             app.removed = true;
   5258                             procs.add(app);
   5259                         }
   5260                     }
   5261                 }
   5262 
   5263                 int N = procs.size();
   5264                 for (int i=0; i<N; i++) {
   5265                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5266                 }
   5267                 mAllowLowerMemLevel = true;
   5268                 updateOomAdjLocked();
   5269                 doLowMemReportIfNeededLocked(null);
   5270             }
   5271         } finally {
   5272             Binder.restoreCallingIdentity(callingId);
   5273         }
   5274     }
   5275 
   5276     @Override
   5277     public void forceStopPackage(final String packageName, int userId) {
   5278         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5279                 != PackageManager.PERMISSION_GRANTED) {
   5280             String msg = "Permission Denial: forceStopPackage() from pid="
   5281                     + Binder.getCallingPid()
   5282                     + ", uid=" + Binder.getCallingUid()
   5283                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5284             Slog.w(TAG, msg);
   5285             throw new SecurityException(msg);
   5286         }
   5287         final int callingPid = Binder.getCallingPid();
   5288         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
   5289                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5290         long callingId = Binder.clearCallingIdentity();
   5291         try {
   5292             IPackageManager pm = AppGlobals.getPackageManager();
   5293             synchronized(this) {
   5294                 int[] users = userId == UserHandle.USER_ALL
   5295                         ? getUsersLocked() : new int[] { userId };
   5296                 for (int user : users) {
   5297                     int pkgUid = -1;
   5298                     try {
   5299                         pkgUid = pm.getPackageUid(packageName, user);
   5300                     } catch (RemoteException e) {
   5301                     }
   5302                     if (pkgUid == -1) {
   5303                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5304                         continue;
   5305                     }
   5306                     try {
   5307                         pm.setPackageStoppedState(packageName, true, user);
   5308                     } catch (RemoteException e) {
   5309                     } catch (IllegalArgumentException e) {
   5310                         Slog.w(TAG, "Failed trying to unstop package "
   5311                                 + packageName + ": " + e);
   5312                     }
   5313                     if (isUserRunningLocked(user, false)) {
   5314                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5315                     }
   5316                 }
   5317             }
   5318         } finally {
   5319             Binder.restoreCallingIdentity(callingId);
   5320         }
   5321     }
   5322 
   5323     @Override
   5324     public void addPackageDependency(String packageName) {
   5325         synchronized (this) {
   5326             int callingPid = Binder.getCallingPid();
   5327             if (callingPid == Process.myPid()) {
   5328                 //  Yeah, um, no.
   5329                 return;
   5330             }
   5331             ProcessRecord proc;
   5332             synchronized (mPidsSelfLocked) {
   5333                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5334             }
   5335             if (proc != null) {
   5336                 if (proc.pkgDeps == null) {
   5337                     proc.pkgDeps = new ArraySet<String>(1);
   5338                 }
   5339                 proc.pkgDeps.add(packageName);
   5340             }
   5341         }
   5342     }
   5343 
   5344     /*
   5345      * The pkg name and app id have to be specified.
   5346      */
   5347     @Override
   5348     public void killApplicationWithAppId(String pkg, int appid, String reason) {
   5349         if (pkg == null) {
   5350             return;
   5351         }
   5352         // Make sure the uid is valid.
   5353         if (appid < 0) {
   5354             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5355             return;
   5356         }
   5357         int callerUid = Binder.getCallingUid();
   5358         // Only the system server can kill an application
   5359         if (callerUid == Process.SYSTEM_UID) {
   5360             // Post an aysnc message to kill the application
   5361             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5362             msg.arg1 = appid;
   5363             msg.arg2 = 0;
   5364             Bundle bundle = new Bundle();
   5365             bundle.putString("pkg", pkg);
   5366             bundle.putString("reason", reason);
   5367             msg.obj = bundle;
   5368             mHandler.sendMessage(msg);
   5369         } else {
   5370             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5371                     pkg);
   5372         }
   5373     }
   5374 
   5375     @Override
   5376     public void closeSystemDialogs(String reason) {
   5377         enforceNotIsolatedCaller("closeSystemDialogs");
   5378 
   5379         final int pid = Binder.getCallingPid();
   5380         final int uid = Binder.getCallingUid();
   5381         final long origId = Binder.clearCallingIdentity();
   5382         try {
   5383             synchronized (this) {
   5384                 // Only allow this from foreground processes, so that background
   5385                 // applications can't abuse it to prevent system UI from being shown.
   5386                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5387                     ProcessRecord proc;
   5388                     synchronized (mPidsSelfLocked) {
   5389                         proc = mPidsSelfLocked.get(pid);
   5390                     }
   5391                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5392                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5393                                 + " from background process " + proc);
   5394                         return;
   5395                     }
   5396                 }
   5397                 closeSystemDialogsLocked(reason);
   5398             }
   5399         } finally {
   5400             Binder.restoreCallingIdentity(origId);
   5401         }
   5402     }
   5403 
   5404     void closeSystemDialogsLocked(String reason) {
   5405         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5406         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5407                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5408         if (reason != null) {
   5409             intent.putExtra("reason", reason);
   5410         }
   5411         mWindowManager.closeSystemDialogs(reason);
   5412 
   5413         mStackSupervisor.closeSystemDialogsLocked();
   5414 
   5415         broadcastIntentLocked(null, null, intent, null,
   5416                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   5417                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   5418     }
   5419 
   5420     @Override
   5421     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5422         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5423         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5424         for (int i=pids.length-1; i>=0; i--) {
   5425             ProcessRecord proc;
   5426             int oomAdj;
   5427             synchronized (this) {
   5428                 synchronized (mPidsSelfLocked) {
   5429                     proc = mPidsSelfLocked.get(pids[i]);
   5430                     oomAdj = proc != null ? proc.setAdj : 0;
   5431                 }
   5432             }
   5433             infos[i] = new Debug.MemoryInfo();
   5434             Debug.getMemoryInfo(pids[i], infos[i]);
   5435             if (proc != null) {
   5436                 synchronized (this) {
   5437                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5438                         // Record this for posterity if the process has been stable.
   5439                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5440                                 infos[i].getTotalUss(), false, proc.pkgList);
   5441                     }
   5442                 }
   5443             }
   5444         }
   5445         return infos;
   5446     }
   5447 
   5448     @Override
   5449     public long[] getProcessPss(int[] pids) {
   5450         enforceNotIsolatedCaller("getProcessPss");
   5451         long[] pss = new long[pids.length];
   5452         for (int i=pids.length-1; i>=0; i--) {
   5453             ProcessRecord proc;
   5454             int oomAdj;
   5455             synchronized (this) {
   5456                 synchronized (mPidsSelfLocked) {
   5457                     proc = mPidsSelfLocked.get(pids[i]);
   5458                     oomAdj = proc != null ? proc.setAdj : 0;
   5459                 }
   5460             }
   5461             long[] tmpUss = new long[1];
   5462             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   5463             if (proc != null) {
   5464                 synchronized (this) {
   5465                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5466                         // Record this for posterity if the process has been stable.
   5467                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5468                     }
   5469                 }
   5470             }
   5471         }
   5472         return pss;
   5473     }
   5474 
   5475     @Override
   5476     public void killApplicationProcess(String processName, int uid) {
   5477         if (processName == null) {
   5478             return;
   5479         }
   5480 
   5481         int callerUid = Binder.getCallingUid();
   5482         // Only the system server can kill an application
   5483         if (callerUid == Process.SYSTEM_UID) {
   5484             synchronized (this) {
   5485                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5486                 if (app != null && app.thread != null) {
   5487                     try {
   5488                         app.thread.scheduleSuicide();
   5489                     } catch (RemoteException e) {
   5490                         // If the other end already died, then our work here is done.
   5491                     }
   5492                 } else {
   5493                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5494                             + processName + " / " + uid);
   5495                 }
   5496             }
   5497         } else {
   5498             throw new SecurityException(callerUid + " cannot kill app process: " +
   5499                     processName);
   5500         }
   5501     }
   5502 
   5503     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5504         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5505                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5506         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5507                 Uri.fromParts("package", packageName, null));
   5508         if (!mProcessesReady) {
   5509             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5510                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5511         }
   5512         intent.putExtra(Intent.EXTRA_UID, uid);
   5513         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5514         broadcastIntentLocked(null, null, intent,
   5515                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5516                 false, false,
   5517                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5518     }
   5519 
   5520     private void forceStopUserLocked(int userId, String reason) {
   5521         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
   5522         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   5523         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5524                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5525         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   5526         broadcastIntentLocked(null, null, intent,
   5527                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5528                 false, false,
   5529                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5530     }
   5531 
   5532     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5533             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5534             boolean doit, boolean evenPersistent, String reason) {
   5535         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5536 
   5537         // Remove all processes this package may have touched: all with the
   5538         // same UID (except for the system or root user), and all whose name
   5539         // matches the package name.
   5540         final int NP = mProcessNames.getMap().size();
   5541         for (int ip=0; ip<NP; ip++) {
   5542             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5543             final int NA = apps.size();
   5544             for (int ia=0; ia<NA; ia++) {
   5545                 ProcessRecord app = apps.valueAt(ia);
   5546                 if (app.persistent && !evenPersistent) {
   5547                     // we don't kill persistent processes
   5548                     continue;
   5549                 }
   5550                 if (app.removed) {
   5551                     if (doit) {
   5552                         procs.add(app);
   5553                     }
   5554                     continue;
   5555                 }
   5556 
   5557                 // Skip process if it doesn't meet our oom adj requirement.
   5558                 if (app.setAdj < minOomAdj) {
   5559                     continue;
   5560                 }
   5561 
   5562                 // If no package is specified, we call all processes under the
   5563                 // give user id.
   5564                 if (packageName == null) {
   5565                     if (app.userId != userId) {
   5566                         continue;
   5567                     }
   5568                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5569                         continue;
   5570                     }
   5571                 // Package has been specified, we want to hit all processes
   5572                 // that match it.  We need to qualify this by the processes
   5573                 // that are running under the specified app and user ID.
   5574                 } else {
   5575                     final boolean isDep = app.pkgDeps != null
   5576                             && app.pkgDeps.contains(packageName);
   5577                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   5578                         continue;
   5579                     }
   5580                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5581                         continue;
   5582                     }
   5583                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   5584                         continue;
   5585                     }
   5586                 }
   5587 
   5588                 // Process has passed all conditions, kill it!
   5589                 if (!doit) {
   5590                     return true;
   5591                 }
   5592                 app.removed = true;
   5593                 procs.add(app);
   5594             }
   5595         }
   5596 
   5597         int N = procs.size();
   5598         for (int i=0; i<N; i++) {
   5599             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   5600         }
   5601         updateOomAdjLocked();
   5602         return N > 0;
   5603     }
   5604 
   5605     private final boolean forceStopPackageLocked(String name, int appId,
   5606             boolean callerWillRestart, boolean purgeCache, boolean doit,
   5607             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   5608         int i;
   5609         int N;
   5610 
   5611         if (userId == UserHandle.USER_ALL && name == null) {
   5612             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   5613         }
   5614 
   5615         if (appId < 0 && name != null) {
   5616             try {
   5617                 appId = UserHandle.getAppId(
   5618                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   5619             } catch (RemoteException e) {
   5620             }
   5621         }
   5622 
   5623         if (doit) {
   5624             if (name != null) {
   5625                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
   5626                         + " user=" + userId + ": " + reason);
   5627             } else {
   5628                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   5629             }
   5630 
   5631             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   5632             for (int ip=pmap.size()-1; ip>=0; ip--) {
   5633                 SparseArray<Long> ba = pmap.valueAt(ip);
   5634                 for (i=ba.size()-1; i>=0; i--) {
   5635                     boolean remove = false;
   5636                     final int entUid = ba.keyAt(i);
   5637                     if (name != null) {
   5638                         if (userId == UserHandle.USER_ALL) {
   5639                             if (UserHandle.getAppId(entUid) == appId) {
   5640                                 remove = true;
   5641                             }
   5642                         } else {
   5643                             if (entUid == UserHandle.getUid(userId, appId)) {
   5644                                 remove = true;
   5645                             }
   5646                         }
   5647                     } else if (UserHandle.getUserId(entUid) == userId) {
   5648                         remove = true;
   5649                     }
   5650                     if (remove) {
   5651                         ba.removeAt(i);
   5652                     }
   5653                 }
   5654                 if (ba.size() == 0) {
   5655                     pmap.removeAt(ip);
   5656                 }
   5657             }
   5658         }
   5659 
   5660         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   5661                 -100, callerWillRestart, true, doit, evenPersistent,
   5662                 name == null ? ("stop user " + userId) : ("stop " + name));
   5663 
   5664         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   5665             if (!doit) {
   5666                 return true;
   5667             }
   5668             didSomething = true;
   5669         }
   5670 
   5671         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   5672             if (!doit) {
   5673                 return true;
   5674             }
   5675             didSomething = true;
   5676         }
   5677 
   5678         if (name == null) {
   5679             // Remove all sticky broadcasts from this user.
   5680             mStickyBroadcasts.remove(userId);
   5681         }
   5682 
   5683         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   5684         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   5685                 userId, providers)) {
   5686             if (!doit) {
   5687                 return true;
   5688             }
   5689             didSomething = true;
   5690         }
   5691         N = providers.size();
   5692         for (i=0; i<N; i++) {
   5693             removeDyingProviderLocked(null, providers.get(i), true);
   5694         }
   5695 
   5696         // Remove transient permissions granted from/to this package/user
   5697         removeUriPermissionsForPackageLocked(name, userId, false);
   5698 
   5699         if (name == null || uninstalling) {
   5700             // Remove pending intents.  For now we only do this when force
   5701             // stopping users, because we have some problems when doing this
   5702             // for packages -- app widgets are not currently cleaned up for
   5703             // such packages, so they can be left with bad pending intents.
   5704             if (mIntentSenderRecords.size() > 0) {
   5705                 Iterator<WeakReference<PendingIntentRecord>> it
   5706                         = mIntentSenderRecords.values().iterator();
   5707                 while (it.hasNext()) {
   5708                     WeakReference<PendingIntentRecord> wpir = it.next();
   5709                     if (wpir == null) {
   5710                         it.remove();
   5711                         continue;
   5712                     }
   5713                     PendingIntentRecord pir = wpir.get();
   5714                     if (pir == null) {
   5715                         it.remove();
   5716                         continue;
   5717                     }
   5718                     if (name == null) {
   5719                         // Stopping user, remove all objects for the user.
   5720                         if (pir.key.userId != userId) {
   5721                             // Not the same user, skip it.
   5722                             continue;
   5723                         }
   5724                     } else {
   5725                         if (UserHandle.getAppId(pir.uid) != appId) {
   5726                             // Different app id, skip it.
   5727                             continue;
   5728                         }
   5729                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   5730                             // Different user, skip it.
   5731                             continue;
   5732                         }
   5733                         if (!pir.key.packageName.equals(name)) {
   5734                             // Different package, skip it.
   5735                             continue;
   5736                         }
   5737                     }
   5738                     if (!doit) {
   5739                         return true;
   5740                     }
   5741                     didSomething = true;
   5742                     it.remove();
   5743                     pir.canceled = true;
   5744                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   5745                         pir.key.activity.pendingResults.remove(pir.ref);
   5746                     }
   5747                 }
   5748             }
   5749         }
   5750 
   5751         if (doit) {
   5752             if (purgeCache && name != null) {
   5753                 AttributeCache ac = AttributeCache.instance();
   5754                 if (ac != null) {
   5755                     ac.removePackage(name);
   5756                 }
   5757             }
   5758             if (mBooted) {
   5759                 mStackSupervisor.resumeTopActivitiesLocked();
   5760                 mStackSupervisor.scheduleIdleLocked();
   5761             }
   5762         }
   5763 
   5764         return didSomething;
   5765     }
   5766 
   5767     private final boolean removeProcessLocked(ProcessRecord app,
   5768             boolean callerWillRestart, boolean allowRestart, String reason) {
   5769         final String name = app.processName;
   5770         final int uid = app.uid;
   5771         if (DEBUG_PROCESSES) Slog.d(
   5772             TAG, "Force removing proc " + app.toShortString() + " (" + name
   5773             + "/" + uid + ")");
   5774 
   5775         mProcessNames.remove(name, uid);
   5776         mIsolatedProcesses.remove(app.uid);
   5777         if (mHeavyWeightProcess == app) {
   5778             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5779                     mHeavyWeightProcess.userId, 0));
   5780             mHeavyWeightProcess = null;
   5781         }
   5782         boolean needRestart = false;
   5783         if (app.pid > 0 && app.pid != MY_PID) {
   5784             int pid = app.pid;
   5785             synchronized (mPidsSelfLocked) {
   5786                 mPidsSelfLocked.remove(pid);
   5787                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5788             }
   5789             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   5790             if (app.isolated) {
   5791                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   5792             }
   5793             app.kill(reason, true);
   5794             handleAppDiedLocked(app, true, allowRestart);
   5795             removeLruProcessLocked(app);
   5796 
   5797             if (app.persistent && !app.isolated) {
   5798                 if (!callerWillRestart) {
   5799                     addAppLocked(app.info, false, null /* ABI override */);
   5800                 } else {
   5801                     needRestart = true;
   5802                 }
   5803             }
   5804         } else {
   5805             mRemovedProcesses.add(app);
   5806         }
   5807 
   5808         return needRestart;
   5809     }
   5810 
   5811     private final void processStartTimedOutLocked(ProcessRecord app) {
   5812         final int pid = app.pid;
   5813         boolean gone = false;
   5814         synchronized (mPidsSelfLocked) {
   5815             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   5816             if (knownApp != null && knownApp.thread == null) {
   5817                 mPidsSelfLocked.remove(pid);
   5818                 gone = true;
   5819             }
   5820         }
   5821 
   5822         if (gone) {
   5823             Slog.w(TAG, "Process " + app + " failed to attach");
   5824             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   5825                     pid, app.uid, app.processName);
   5826             mProcessNames.remove(app.processName, app.uid);
   5827             mIsolatedProcesses.remove(app.uid);
   5828             if (mHeavyWeightProcess == app) {
   5829                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5830                         mHeavyWeightProcess.userId, 0));
   5831                 mHeavyWeightProcess = null;
   5832             }
   5833             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   5834             if (app.isolated) {
   5835                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   5836             }
   5837             // Take care of any launching providers waiting for this process.
   5838             checkAppInLaunchingProvidersLocked(app, true);
   5839             // Take care of any services that are waiting for the process.
   5840             mServices.processStartTimedOutLocked(app);
   5841             app.kill("start timeout", true);
   5842             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   5843                 Slog.w(TAG, "Unattached app died before backup, skipping");
   5844                 try {
   5845                     IBackupManager bm = IBackupManager.Stub.asInterface(
   5846                             ServiceManager.getService(Context.BACKUP_SERVICE));
   5847                     bm.agentDisconnected(app.info.packageName);
   5848                 } catch (RemoteException e) {
   5849                     // Can't happen; the backup manager is local
   5850                 }
   5851             }
   5852             if (isPendingBroadcastProcessLocked(pid)) {
   5853                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   5854                 skipPendingBroadcastLocked(pid);
   5855             }
   5856         } else {
   5857             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   5858         }
   5859     }
   5860 
   5861     private final boolean attachApplicationLocked(IApplicationThread thread,
   5862             int pid) {
   5863 
   5864         // Find the application record that is being attached...  either via
   5865         // the pid if we are running in multiple processes, or just pull the
   5866         // next app record if we are emulating process with anonymous threads.
   5867         ProcessRecord app;
   5868         if (pid != MY_PID && pid >= 0) {
   5869             synchronized (mPidsSelfLocked) {
   5870                 app = mPidsSelfLocked.get(pid);
   5871             }
   5872         } else {
   5873             app = null;
   5874         }
   5875 
   5876         if (app == null) {
   5877             Slog.w(TAG, "No pending application record for pid " + pid
   5878                     + " (IApplicationThread " + thread + "); dropping process");
   5879             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   5880             if (pid > 0 && pid != MY_PID) {
   5881                 Process.killProcessQuiet(pid);
   5882                 //TODO: Process.killProcessGroup(app.info.uid, pid);
   5883             } else {
   5884                 try {
   5885                     thread.scheduleExit();
   5886                 } catch (Exception e) {
   5887                     // Ignore exceptions.
   5888                 }
   5889             }
   5890             return false;
   5891         }
   5892 
   5893         // If this application record is still attached to a previous
   5894         // process, clean it up now.
   5895         if (app.thread != null) {
   5896             handleAppDiedLocked(app, true, true);
   5897         }
   5898 
   5899         // Tell the process all about itself.
   5900 
   5901         if (localLOGV) Slog.v(
   5902                 TAG, "Binding process pid " + pid + " to record " + app);
   5903 
   5904         final String processName = app.processName;
   5905         try {
   5906             AppDeathRecipient adr = new AppDeathRecipient(
   5907                     app, pid, thread);
   5908             thread.asBinder().linkToDeath(adr, 0);
   5909             app.deathRecipient = adr;
   5910         } catch (RemoteException e) {
   5911             app.resetPackageList(mProcessStats);
   5912             startProcessLocked(app, "link fail", processName);
   5913             return false;
   5914         }
   5915 
   5916         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   5917 
   5918         app.makeActive(thread, mProcessStats);
   5919         app.curAdj = app.setAdj = -100;
   5920         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
   5921         app.forcingToForeground = null;
   5922         updateProcessForegroundLocked(app, false, false);
   5923         app.hasShownUi = false;
   5924         app.debugging = false;
   5925         app.cached = false;
   5926         app.killedByAm = false;
   5927 
   5928         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5929 
   5930         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   5931         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   5932 
   5933         if (!normalMode) {
   5934             Slog.i(TAG, "Launching preboot mode app: " + app);
   5935         }
   5936 
   5937         if (localLOGV) Slog.v(
   5938             TAG, "New app record " + app
   5939             + " thread=" + thread.asBinder() + " pid=" + pid);
   5940         try {
   5941             int testMode = IApplicationThread.DEBUG_OFF;
   5942             if (mDebugApp != null && mDebugApp.equals(processName)) {
   5943                 testMode = mWaitForDebugger
   5944                     ? IApplicationThread.DEBUG_WAIT
   5945                     : IApplicationThread.DEBUG_ON;
   5946                 app.debugging = true;
   5947                 if (mDebugTransient) {
   5948                     mDebugApp = mOrigDebugApp;
   5949                     mWaitForDebugger = mOrigWaitForDebugger;
   5950                 }
   5951             }
   5952             String profileFile = app.instrumentationProfileFile;
   5953             ParcelFileDescriptor profileFd = null;
   5954             int samplingInterval = 0;
   5955             boolean profileAutoStop = false;
   5956             if (mProfileApp != null && mProfileApp.equals(processName)) {
   5957                 mProfileProc = app;
   5958                 profileFile = mProfileFile;
   5959                 profileFd = mProfileFd;
   5960                 samplingInterval = mSamplingInterval;
   5961                 profileAutoStop = mAutoStopProfiler;
   5962             }
   5963             boolean enableOpenGlTrace = false;
   5964             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   5965                 enableOpenGlTrace = true;
   5966                 mOpenGlTraceApp = null;
   5967             }
   5968 
   5969             // If the app is being launched for restore or full backup, set it up specially
   5970             boolean isRestrictedBackupMode = false;
   5971             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   5972                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   5973                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   5974                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   5975             }
   5976 
   5977             ensurePackageDexOpt(app.instrumentationInfo != null
   5978                     ? app.instrumentationInfo.packageName
   5979                     : app.info.packageName);
   5980             if (app.instrumentationClass != null) {
   5981                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   5982             }
   5983             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   5984                     + processName + " with config " + mConfiguration);
   5985             ApplicationInfo appInfo = app.instrumentationInfo != null
   5986                     ? app.instrumentationInfo : app.info;
   5987             app.compat = compatibilityInfoForPackageLocked(appInfo);
   5988             if (profileFd != null) {
   5989                 profileFd = profileFd.dup();
   5990             }
   5991             ProfilerInfo profilerInfo = profileFile == null ? null
   5992                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   5993             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   5994                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   5995                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   5996                     isRestrictedBackupMode || !normalMode, app.persistent,
   5997                     new Configuration(mConfiguration), app.compat,
   5998                     getCommonServicesLocked(app.isolated),
   5999                     mCoreSettingsObserver.getCoreSettingsLocked());
   6000             updateLruProcessLocked(app, false, null);
   6001             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6002         } catch (Exception e) {
   6003             // todo: Yikes!  What should we do?  For now we will try to
   6004             // start another process, but that could easily get us in
   6005             // an infinite loop of restarting processes...
   6006             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6007 
   6008             app.resetPackageList(mProcessStats);
   6009             app.unlinkDeathRecipient();
   6010             startProcessLocked(app, "bind fail", processName);
   6011             return false;
   6012         }
   6013 
   6014         // Remove this record from the list of starting applications.
   6015         mPersistentStartingProcesses.remove(app);
   6016         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   6017                 "Attach application locked removing on hold: " + app);
   6018         mProcessesOnHold.remove(app);
   6019 
   6020         boolean badApp = false;
   6021         boolean didSomething = false;
   6022 
   6023         // See if the top visible activity is waiting to run in this process...
   6024         if (normalMode) {
   6025             try {
   6026                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6027                     didSomething = true;
   6028                 }
   6029             } catch (Exception e) {
   6030                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6031                 badApp = true;
   6032             }
   6033         }
   6034 
   6035         // Find any services that should be running in this process...
   6036         if (!badApp) {
   6037             try {
   6038                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6039             } catch (Exception e) {
   6040                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6041                 badApp = true;
   6042             }
   6043         }
   6044 
   6045         // Check if a next-broadcast receiver is in this process...
   6046         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6047             try {
   6048                 didSomething |= sendPendingBroadcastsLocked(app);
   6049             } catch (Exception e) {
   6050                 // If the app died trying to launch the receiver we declare it 'bad'
   6051                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6052                 badApp = true;
   6053             }
   6054         }
   6055 
   6056         // Check whether the next backup agent is in this process...
   6057         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6058             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   6059             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   6060             try {
   6061                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6062                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6063                         mBackupTarget.backupMode);
   6064             } catch (Exception e) {
   6065                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6066                 badApp = true;
   6067             }
   6068         }
   6069 
   6070         if (badApp) {
   6071             app.kill("error during init", true);
   6072             handleAppDiedLocked(app, false, true);
   6073             return false;
   6074         }
   6075 
   6076         if (!didSomething) {
   6077             updateOomAdjLocked();
   6078         }
   6079 
   6080         return true;
   6081     }
   6082 
   6083     @Override
   6084     public final void attachApplication(IApplicationThread thread) {
   6085         synchronized (this) {
   6086             int callingPid = Binder.getCallingPid();
   6087             final long origId = Binder.clearCallingIdentity();
   6088             attachApplicationLocked(thread, callingPid);
   6089             Binder.restoreCallingIdentity(origId);
   6090         }
   6091     }
   6092 
   6093     @Override
   6094     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6095         final long origId = Binder.clearCallingIdentity();
   6096         synchronized (this) {
   6097             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6098             if (stack != null) {
   6099                 ActivityRecord r =
   6100                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6101                 if (stopProfiling) {
   6102                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6103                         try {
   6104                             mProfileFd.close();
   6105                         } catch (IOException e) {
   6106                         }
   6107                         clearProfilerLocked();
   6108                     }
   6109                 }
   6110             }
   6111         }
   6112         Binder.restoreCallingIdentity(origId);
   6113     }
   6114 
   6115     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6116         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6117                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
   6118     }
   6119 
   6120     void enableScreenAfterBoot() {
   6121         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6122                 SystemClock.uptimeMillis());
   6123         mWindowManager.enableScreenAfterBoot();
   6124 
   6125         synchronized (this) {
   6126             updateEventDispatchingLocked();
   6127         }
   6128     }
   6129 
   6130     @Override
   6131     public void showBootMessage(final CharSequence msg, final boolean always) {
   6132         enforceNotIsolatedCaller("showBootMessage");
   6133         mWindowManager.showBootMessage(msg, always);
   6134     }
   6135 
   6136     @Override
   6137     public void keyguardWaitingForActivityDrawn() {
   6138         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6139         final long token = Binder.clearCallingIdentity();
   6140         try {
   6141             synchronized (this) {
   6142                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6143                 mWindowManager.keyguardWaitingForActivityDrawn();
   6144                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6145                     mLockScreenShown = LOCK_SCREEN_LEAVING;
   6146                     updateSleepIfNeededLocked();
   6147                 }
   6148             }
   6149         } finally {
   6150             Binder.restoreCallingIdentity(token);
   6151         }
   6152     }
   6153 
   6154     final void finishBooting() {
   6155         synchronized (this) {
   6156             if (!mBootAnimationComplete) {
   6157                 mCallFinishBooting = true;
   6158                 return;
   6159             }
   6160             mCallFinishBooting = false;
   6161         }
   6162 
   6163         ArraySet<String> completedIsas = new ArraySet<String>();
   6164         for (String abi : Build.SUPPORTED_ABIS) {
   6165             Process.establishZygoteConnectionForAbi(abi);
   6166             final String instructionSet = VMRuntime.getInstructionSet(abi);
   6167             if (!completedIsas.contains(instructionSet)) {
   6168                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
   6169                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
   6170                 }
   6171                 completedIsas.add(instructionSet);
   6172             }
   6173         }
   6174 
   6175         IntentFilter pkgFilter = new IntentFilter();
   6176         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   6177         pkgFilter.addDataScheme("package");
   6178         mContext.registerReceiver(new BroadcastReceiver() {
   6179             @Override
   6180             public void onReceive(Context context, Intent intent) {
   6181                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   6182                 if (pkgs != null) {
   6183                     for (String pkg : pkgs) {
   6184                         synchronized (ActivityManagerService.this) {
   6185                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   6186                                     0, "finished booting")) {
   6187                                 setResultCode(Activity.RESULT_OK);
   6188                                 return;
   6189                             }
   6190                         }
   6191                     }
   6192                 }
   6193             }
   6194         }, pkgFilter);
   6195 
   6196         // Let system services know.
   6197         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6198 
   6199         synchronized (this) {
   6200             // Ensure that any processes we had put on hold are now started
   6201             // up.
   6202             final int NP = mProcessesOnHold.size();
   6203             if (NP > 0) {
   6204                 ArrayList<ProcessRecord> procs =
   6205                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6206                 for (int ip=0; ip<NP; ip++) {
   6207                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   6208                             + procs.get(ip));
   6209                     startProcessLocked(procs.get(ip), "on-hold", null);
   6210                 }
   6211             }
   6212 
   6213             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6214                 // Start looking for apps that are abusing wake locks.
   6215                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6216                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6217                 // Tell anyone interested that we are done booting!
   6218                 SystemProperties.set("sys.boot_completed", "1");
   6219 
   6220                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6221                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6222                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6223                     SystemProperties.set("dev.bootcomplete", "1");
   6224                 }
   6225                 for (int i=0; i<mStartedUsers.size(); i++) {
   6226                     UserStartedState uss = mStartedUsers.valueAt(i);
   6227                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   6228                         uss.mState = UserStartedState.STATE_RUNNING;
   6229                         final int userId = mStartedUsers.keyAt(i);
   6230                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   6231                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   6232                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   6233                         broadcastIntentLocked(null, null, intent, null,
   6234                                 new IIntentReceiver.Stub() {
   6235                                     @Override
   6236                                     public void performReceive(Intent intent, int resultCode,
   6237                                             String data, Bundle extras, boolean ordered,
   6238                                             boolean sticky, int sendingUser) {
   6239                                         synchronized (ActivityManagerService.this) {
   6240                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6241                                                     true, false);
   6242                                         }
   6243                                     }
   6244                                 },
   6245                                 0, null, null,
   6246                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   6247                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
   6248                                 userId);
   6249                     }
   6250                 }
   6251                 scheduleStartProfilesLocked();
   6252             }
   6253         }
   6254     }
   6255 
   6256     @Override
   6257     public void bootAnimationComplete() {
   6258         final boolean callFinishBooting;
   6259         synchronized (this) {
   6260             callFinishBooting = mCallFinishBooting;
   6261             mBootAnimationComplete = true;
   6262         }
   6263         if (callFinishBooting) {
   6264             finishBooting();
   6265         }
   6266     }
   6267 
   6268     @Override
   6269     public void systemBackupRestored() {
   6270         synchronized (this) {
   6271             if (mSystemReady) {
   6272                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
   6273             } else {
   6274                 Slog.w(TAG, "System backup restored before system is ready");
   6275             }
   6276         }
   6277     }
   6278 
   6279     final void ensureBootCompleted() {
   6280         boolean booting;
   6281         boolean enableScreen;
   6282         synchronized (this) {
   6283             booting = mBooting;
   6284             mBooting = false;
   6285             enableScreen = !mBooted;
   6286             mBooted = true;
   6287         }
   6288 
   6289         if (booting) {
   6290             finishBooting();
   6291         }
   6292 
   6293         if (enableScreen) {
   6294             enableScreenAfterBoot();
   6295         }
   6296     }
   6297 
   6298     @Override
   6299     public final void activityResumed(IBinder token) {
   6300         final long origId = Binder.clearCallingIdentity();
   6301         synchronized(this) {
   6302             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6303             if (stack != null) {
   6304                 ActivityRecord.activityResumedLocked(token);
   6305             }
   6306         }
   6307         Binder.restoreCallingIdentity(origId);
   6308     }
   6309 
   6310     @Override
   6311     public final void activityPaused(IBinder token) {
   6312         final long origId = Binder.clearCallingIdentity();
   6313         synchronized(this) {
   6314             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6315             if (stack != null) {
   6316                 stack.activityPausedLocked(token, false);
   6317             }
   6318         }
   6319         Binder.restoreCallingIdentity(origId);
   6320     }
   6321 
   6322     @Override
   6323     public final void activityStopped(IBinder token, Bundle icicle,
   6324             PersistableBundle persistentState, CharSequence description) {
   6325         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
   6326 
   6327         // Refuse possible leaked file descriptors
   6328         if (icicle != null && icicle.hasFileDescriptors()) {
   6329             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6330         }
   6331 
   6332         final long origId = Binder.clearCallingIdentity();
   6333 
   6334         synchronized (this) {
   6335             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6336             if (r != null) {
   6337                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6338             }
   6339         }
   6340 
   6341         trimApplications();
   6342 
   6343         Binder.restoreCallingIdentity(origId);
   6344     }
   6345 
   6346     @Override
   6347     public final void activityDestroyed(IBinder token) {
   6348         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   6349         synchronized (this) {
   6350             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6351             if (stack != null) {
   6352                 stack.activityDestroyedLocked(token, "activityDestroyed");
   6353             }
   6354         }
   6355     }
   6356 
   6357     @Override
   6358     public final void backgroundResourcesReleased(IBinder token) {
   6359         final long origId = Binder.clearCallingIdentity();
   6360         try {
   6361             synchronized (this) {
   6362                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6363                 if (stack != null) {
   6364                     stack.backgroundResourcesReleased();
   6365                 }
   6366             }
   6367         } finally {
   6368             Binder.restoreCallingIdentity(origId);
   6369         }
   6370     }
   6371 
   6372     @Override
   6373     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   6374         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   6375     }
   6376 
   6377     @Override
   6378     public final void notifyEnterAnimationComplete(IBinder token) {
   6379         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   6380     }
   6381 
   6382     @Override
   6383     public String getCallingPackage(IBinder token) {
   6384         synchronized (this) {
   6385             ActivityRecord r = getCallingRecordLocked(token);
   6386             return r != null ? r.info.packageName : null;
   6387         }
   6388     }
   6389 
   6390     @Override
   6391     public ComponentName getCallingActivity(IBinder token) {
   6392         synchronized (this) {
   6393             ActivityRecord r = getCallingRecordLocked(token);
   6394             return r != null ? r.intent.getComponent() : null;
   6395         }
   6396     }
   6397 
   6398     private ActivityRecord getCallingRecordLocked(IBinder token) {
   6399         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6400         if (r == null) {
   6401             return null;
   6402         }
   6403         return r.resultTo;
   6404     }
   6405 
   6406     @Override
   6407     public ComponentName getActivityClassForToken(IBinder token) {
   6408         synchronized(this) {
   6409             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6410             if (r == null) {
   6411                 return null;
   6412             }
   6413             return r.intent.getComponent();
   6414         }
   6415     }
   6416 
   6417     @Override
   6418     public String getPackageForToken(IBinder token) {
   6419         synchronized(this) {
   6420             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6421             if (r == null) {
   6422                 return null;
   6423             }
   6424             return r.packageName;
   6425         }
   6426     }
   6427 
   6428     @Override
   6429     public IIntentSender getIntentSender(int type,
   6430             String packageName, IBinder token, String resultWho,
   6431             int requestCode, Intent[] intents, String[] resolvedTypes,
   6432             int flags, Bundle options, int userId) {
   6433         enforceNotIsolatedCaller("getIntentSender");
   6434         // Refuse possible leaked file descriptors
   6435         if (intents != null) {
   6436             if (intents.length < 1) {
   6437                 throw new IllegalArgumentException("Intents array length must be >= 1");
   6438             }
   6439             for (int i=0; i<intents.length; i++) {
   6440                 Intent intent = intents[i];
   6441                 if (intent != null) {
   6442                     if (intent.hasFileDescriptors()) {
   6443                         throw new IllegalArgumentException("File descriptors passed in Intent");
   6444                     }
   6445                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   6446                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   6447                         throw new IllegalArgumentException(
   6448                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   6449                     }
   6450                     intents[i] = new Intent(intent);
   6451                 }
   6452             }
   6453             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   6454                 throw new IllegalArgumentException(
   6455                         "Intent array length does not match resolvedTypes length");
   6456             }
   6457         }
   6458         if (options != null) {
   6459             if (options.hasFileDescriptors()) {
   6460                 throw new IllegalArgumentException("File descriptors passed in options");
   6461             }
   6462         }
   6463 
   6464         synchronized(this) {
   6465             int callingUid = Binder.getCallingUid();
   6466             int origUserId = userId;
   6467             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   6468                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   6469                     ALLOW_NON_FULL, "getIntentSender", null);
   6470             if (origUserId == UserHandle.USER_CURRENT) {
   6471                 // We don't want to evaluate this until the pending intent is
   6472                 // actually executed.  However, we do want to always do the
   6473                 // security checking for it above.
   6474                 userId = UserHandle.USER_CURRENT;
   6475             }
   6476             try {
   6477                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   6478                     int uid = AppGlobals.getPackageManager()
   6479                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   6480                     if (!UserHandle.isSameApp(callingUid, uid)) {
   6481                         String msg = "Permission Denial: getIntentSender() from pid="
   6482                             + Binder.getCallingPid()
   6483                             + ", uid=" + Binder.getCallingUid()
   6484                             + ", (need uid=" + uid + ")"
   6485                             + " is not allowed to send as package " + packageName;
   6486                         Slog.w(TAG, msg);
   6487                         throw new SecurityException(msg);
   6488                     }
   6489                 }
   6490 
   6491                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   6492                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   6493 
   6494             } catch (RemoteException e) {
   6495                 throw new SecurityException(e);
   6496             }
   6497         }
   6498     }
   6499 
   6500     IIntentSender getIntentSenderLocked(int type, String packageName,
   6501             int callingUid, int userId, IBinder token, String resultWho,
   6502             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   6503             Bundle options) {
   6504         if (DEBUG_MU)
   6505             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   6506         ActivityRecord activity = null;
   6507         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6508             activity = ActivityRecord.isInStackLocked(token);
   6509             if (activity == null) {
   6510                 return null;
   6511             }
   6512             if (activity.finishing) {
   6513                 return null;
   6514             }
   6515         }
   6516 
   6517         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   6518         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   6519         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   6520         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   6521                 |PendingIntent.FLAG_UPDATE_CURRENT);
   6522 
   6523         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   6524                 type, packageName, activity, resultWho,
   6525                 requestCode, intents, resolvedTypes, flags, options, userId);
   6526         WeakReference<PendingIntentRecord> ref;
   6527         ref = mIntentSenderRecords.get(key);
   6528         PendingIntentRecord rec = ref != null ? ref.get() : null;
   6529         if (rec != null) {
   6530             if (!cancelCurrent) {
   6531                 if (updateCurrent) {
   6532                     if (rec.key.requestIntent != null) {
   6533                         rec.key.requestIntent.replaceExtras(intents != null ?
   6534                                 intents[intents.length - 1] : null);
   6535                     }
   6536                     if (intents != null) {
   6537                         intents[intents.length-1] = rec.key.requestIntent;
   6538                         rec.key.allIntents = intents;
   6539                         rec.key.allResolvedTypes = resolvedTypes;
   6540                     } else {
   6541                         rec.key.allIntents = null;
   6542                         rec.key.allResolvedTypes = null;
   6543                     }
   6544                 }
   6545                 return rec;
   6546             }
   6547             rec.canceled = true;
   6548             mIntentSenderRecords.remove(key);
   6549         }
   6550         if (noCreate) {
   6551             return rec;
   6552         }
   6553         rec = new PendingIntentRecord(this, key, callingUid);
   6554         mIntentSenderRecords.put(key, rec.ref);
   6555         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6556             if (activity.pendingResults == null) {
   6557                 activity.pendingResults
   6558                         = new HashSet<WeakReference<PendingIntentRecord>>();
   6559             }
   6560             activity.pendingResults.add(rec.ref);
   6561         }
   6562         return rec;
   6563     }
   6564 
   6565     @Override
   6566     public void cancelIntentSender(IIntentSender sender) {
   6567         if (!(sender instanceof PendingIntentRecord)) {
   6568             return;
   6569         }
   6570         synchronized(this) {
   6571             PendingIntentRecord rec = (PendingIntentRecord)sender;
   6572             try {
   6573                 int uid = AppGlobals.getPackageManager()
   6574                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   6575                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   6576                     String msg = "Permission Denial: cancelIntentSender() from pid="
   6577                         + Binder.getCallingPid()
   6578                         + ", uid=" + Binder.getCallingUid()
   6579                         + " is not allowed to cancel packges "
   6580                         + rec.key.packageName;
   6581                     Slog.w(TAG, msg);
   6582                     throw new SecurityException(msg);
   6583                 }
   6584             } catch (RemoteException e) {
   6585                 throw new SecurityException(e);
   6586             }
   6587             cancelIntentSenderLocked(rec, true);
   6588         }
   6589     }
   6590 
   6591     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   6592         rec.canceled = true;
   6593         mIntentSenderRecords.remove(rec.key);
   6594         if (cleanActivity && rec.key.activity != null) {
   6595             rec.key.activity.pendingResults.remove(rec.ref);
   6596         }
   6597     }
   6598 
   6599     @Override
   6600     public String getPackageForIntentSender(IIntentSender pendingResult) {
   6601         if (!(pendingResult instanceof PendingIntentRecord)) {
   6602             return null;
   6603         }
   6604         try {
   6605             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6606             return res.key.packageName;
   6607         } catch (ClassCastException e) {
   6608         }
   6609         return null;
   6610     }
   6611 
   6612     @Override
   6613     public int getUidForIntentSender(IIntentSender sender) {
   6614         if (sender instanceof PendingIntentRecord) {
   6615             try {
   6616                 PendingIntentRecord res = (PendingIntentRecord)sender;
   6617                 return res.uid;
   6618             } catch (ClassCastException e) {
   6619             }
   6620         }
   6621         return -1;
   6622     }
   6623 
   6624     @Override
   6625     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   6626         if (!(pendingResult instanceof PendingIntentRecord)) {
   6627             return false;
   6628         }
   6629         try {
   6630             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6631             if (res.key.allIntents == null) {
   6632                 return false;
   6633             }
   6634             for (int i=0; i<res.key.allIntents.length; i++) {
   6635                 Intent intent = res.key.allIntents[i];
   6636                 if (intent.getPackage() != null && intent.getComponent() != null) {
   6637                     return false;
   6638                 }
   6639             }
   6640             return true;
   6641         } catch (ClassCastException e) {
   6642         }
   6643         return false;
   6644     }
   6645 
   6646     @Override
   6647     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   6648         if (!(pendingResult instanceof PendingIntentRecord)) {
   6649             return false;
   6650         }
   6651         try {
   6652             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6653             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   6654                 return true;
   6655             }
   6656             return false;
   6657         } catch (ClassCastException e) {
   6658         }
   6659         return false;
   6660     }
   6661 
   6662     @Override
   6663     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   6664         if (!(pendingResult instanceof PendingIntentRecord)) {
   6665             return null;
   6666         }
   6667         try {
   6668             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6669             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   6670         } catch (ClassCastException e) {
   6671         }
   6672         return null;
   6673     }
   6674 
   6675     @Override
   6676     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   6677         if (!(pendingResult instanceof PendingIntentRecord)) {
   6678             return null;
   6679         }
   6680         try {
   6681             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6682             Intent intent = res.key.requestIntent;
   6683             if (intent != null) {
   6684                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   6685                         || res.lastTagPrefix.equals(prefix))) {
   6686                     return res.lastTag;
   6687                 }
   6688                 res.lastTagPrefix = prefix;
   6689                 StringBuilder sb = new StringBuilder(128);
   6690                 if (prefix != null) {
   6691                     sb.append(prefix);
   6692                 }
   6693                 if (intent.getAction() != null) {
   6694                     sb.append(intent.getAction());
   6695                 } else if (intent.getComponent() != null) {
   6696                     intent.getComponent().appendShortString(sb);
   6697                 } else {
   6698                     sb.append("?");
   6699                 }
   6700                 return res.lastTag = sb.toString();
   6701             }
   6702         } catch (ClassCastException e) {
   6703         }
   6704         return null;
   6705     }
   6706 
   6707     @Override
   6708     public void setProcessLimit(int max) {
   6709         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6710                 "setProcessLimit()");
   6711         synchronized (this) {
   6712             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   6713             mProcessLimitOverride = max;
   6714         }
   6715         trimApplications();
   6716     }
   6717 
   6718     @Override
   6719     public int getProcessLimit() {
   6720         synchronized (this) {
   6721             return mProcessLimitOverride;
   6722         }
   6723     }
   6724 
   6725     void foregroundTokenDied(ForegroundToken token) {
   6726         synchronized (ActivityManagerService.this) {
   6727             synchronized (mPidsSelfLocked) {
   6728                 ForegroundToken cur
   6729                     = mForegroundProcesses.get(token.pid);
   6730                 if (cur != token) {
   6731                     return;
   6732                 }
   6733                 mForegroundProcesses.remove(token.pid);
   6734                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   6735                 if (pr == null) {
   6736                     return;
   6737                 }
   6738                 pr.forcingToForeground = null;
   6739                 updateProcessForegroundLocked(pr, false, false);
   6740             }
   6741             updateOomAdjLocked();
   6742         }
   6743     }
   6744 
   6745     @Override
   6746     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   6747         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6748                 "setProcessForeground()");
   6749         synchronized(this) {
   6750             boolean changed = false;
   6751 
   6752             synchronized (mPidsSelfLocked) {
   6753                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   6754                 if (pr == null && isForeground) {
   6755                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   6756                     return;
   6757                 }
   6758                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   6759                 if (oldToken != null) {
   6760                     oldToken.token.unlinkToDeath(oldToken, 0);
   6761                     mForegroundProcesses.remove(pid);
   6762                     if (pr != null) {
   6763                         pr.forcingToForeground = null;
   6764                     }
   6765                     changed = true;
   6766                 }
   6767                 if (isForeground && token != null) {
   6768                     ForegroundToken newToken = new ForegroundToken() {
   6769                         @Override
   6770                         public void binderDied() {
   6771                             foregroundTokenDied(this);
   6772                         }
   6773                     };
   6774                     newToken.pid = pid;
   6775                     newToken.token = token;
   6776                     try {
   6777                         token.linkToDeath(newToken, 0);
   6778                         mForegroundProcesses.put(pid, newToken);
   6779                         pr.forcingToForeground = token;
   6780                         changed = true;
   6781                     } catch (RemoteException e) {
   6782                         // If the process died while doing this, we will later
   6783                         // do the cleanup with the process death link.
   6784                     }
   6785                 }
   6786             }
   6787 
   6788             if (changed) {
   6789                 updateOomAdjLocked();
   6790             }
   6791         }
   6792     }
   6793 
   6794     // =========================================================
   6795     // PERMISSIONS
   6796     // =========================================================
   6797 
   6798     static class PermissionController extends IPermissionController.Stub {
   6799         ActivityManagerService mActivityManagerService;
   6800         PermissionController(ActivityManagerService activityManagerService) {
   6801             mActivityManagerService = activityManagerService;
   6802         }
   6803 
   6804         @Override
   6805         public boolean checkPermission(String permission, int pid, int uid) {
   6806             return mActivityManagerService.checkPermission(permission, pid,
   6807                     uid) == PackageManager.PERMISSION_GRANTED;
   6808         }
   6809     }
   6810 
   6811     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   6812         @Override
   6813         public int checkComponentPermission(String permission, int pid, int uid,
   6814                 int owningUid, boolean exported) {
   6815             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   6816                     owningUid, exported);
   6817         }
   6818 
   6819         @Override
   6820         public Object getAMSLock() {
   6821             return ActivityManagerService.this;
   6822         }
   6823     }
   6824 
   6825     /**
   6826      * This can be called with or without the global lock held.
   6827      */
   6828     int checkComponentPermission(String permission, int pid, int uid,
   6829             int owningUid, boolean exported) {
   6830         if (pid == MY_PID) {
   6831             return PackageManager.PERMISSION_GRANTED;
   6832         }
   6833         return ActivityManager.checkComponentPermission(permission, uid,
   6834                 owningUid, exported);
   6835     }
   6836 
   6837     /**
   6838      * As the only public entry point for permissions checking, this method
   6839      * can enforce the semantic that requesting a check on a null global
   6840      * permission is automatically denied.  (Internally a null permission
   6841      * string is used when calling {@link #checkComponentPermission} in cases
   6842      * when only uid-based security is needed.)
   6843      *
   6844      * This can be called with or without the global lock held.
   6845      */
   6846     @Override
   6847     public int checkPermission(String permission, int pid, int uid) {
   6848         if (permission == null) {
   6849             return PackageManager.PERMISSION_DENIED;
   6850         }
   6851         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   6852     }
   6853 
   6854     @Override
   6855     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   6856         if (permission == null) {
   6857             return PackageManager.PERMISSION_DENIED;
   6858         }
   6859 
   6860         // We might be performing an operation on behalf of an indirect binder
   6861         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   6862         // client identity accordingly before proceeding.
   6863         Identity tlsIdentity = sCallerIdentity.get();
   6864         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   6865             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   6866                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   6867             uid = tlsIdentity.uid;
   6868             pid = tlsIdentity.pid;
   6869         }
   6870 
   6871         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   6872     }
   6873 
   6874     /**
   6875      * Binder IPC calls go through the public entry point.
   6876      * This can be called with or without the global lock held.
   6877      */
   6878     int checkCallingPermission(String permission) {
   6879         return checkPermission(permission,
   6880                 Binder.getCallingPid(),
   6881                 UserHandle.getAppId(Binder.getCallingUid()));
   6882     }
   6883 
   6884     /**
   6885      * This can be called with or without the global lock held.
   6886      */
   6887     void enforceCallingPermission(String permission, String func) {
   6888         if (checkCallingPermission(permission)
   6889                 == PackageManager.PERMISSION_GRANTED) {
   6890             return;
   6891         }
   6892 
   6893         String msg = "Permission Denial: " + func + " from pid="
   6894                 + Binder.getCallingPid()
   6895                 + ", uid=" + Binder.getCallingUid()
   6896                 + " requires " + permission;
   6897         Slog.w(TAG, msg);
   6898         throw new SecurityException(msg);
   6899     }
   6900 
   6901     /**
   6902      * Determine if UID is holding permissions required to access {@link Uri} in
   6903      * the given {@link ProviderInfo}. Final permission checking is always done
   6904      * in {@link ContentProvider}.
   6905      */
   6906     private final boolean checkHoldingPermissionsLocked(
   6907             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   6908         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6909                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   6910         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   6911             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   6912                     != PERMISSION_GRANTED) {
   6913                 return false;
   6914             }
   6915         }
   6916         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   6917     }
   6918 
   6919     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   6920             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   6921         if (pi.applicationInfo.uid == uid) {
   6922             return true;
   6923         } else if (!pi.exported) {
   6924             return false;
   6925         }
   6926 
   6927         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   6928         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   6929         try {
   6930             // check if target holds top-level <provider> permissions
   6931             if (!readMet && pi.readPermission != null && considerUidPermissions
   6932                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   6933                 readMet = true;
   6934             }
   6935             if (!writeMet && pi.writePermission != null && considerUidPermissions
   6936                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   6937                 writeMet = true;
   6938             }
   6939 
   6940             // track if unprotected read/write is allowed; any denied
   6941             // <path-permission> below removes this ability
   6942             boolean allowDefaultRead = pi.readPermission == null;
   6943             boolean allowDefaultWrite = pi.writePermission == null;
   6944 
   6945             // check if target holds any <path-permission> that match uri
   6946             final PathPermission[] pps = pi.pathPermissions;
   6947             if (pps != null) {
   6948                 final String path = grantUri.uri.getPath();
   6949                 int i = pps.length;
   6950                 while (i > 0 && (!readMet || !writeMet)) {
   6951                     i--;
   6952                     PathPermission pp = pps[i];
   6953                     if (pp.match(path)) {
   6954                         if (!readMet) {
   6955                             final String pprperm = pp.getReadPermission();
   6956                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   6957                                     + pprperm + " for " + pp.getPath()
   6958                                     + ": match=" + pp.match(path)
   6959                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   6960                             if (pprperm != null) {
   6961                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   6962                                         == PERMISSION_GRANTED) {
   6963                                     readMet = true;
   6964                                 } else {
   6965                                     allowDefaultRead = false;
   6966                                 }
   6967                             }
   6968                         }
   6969                         if (!writeMet) {
   6970                             final String ppwperm = pp.getWritePermission();
   6971                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   6972                                     + ppwperm + " for " + pp.getPath()
   6973                                     + ": match=" + pp.match(path)
   6974                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   6975                             if (ppwperm != null) {
   6976                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   6977                                         == PERMISSION_GRANTED) {
   6978                                     writeMet = true;
   6979                                 } else {
   6980                                     allowDefaultWrite = false;
   6981                                 }
   6982                             }
   6983                         }
   6984                     }
   6985                 }
   6986             }
   6987 
   6988             // grant unprotected <provider> read/write, if not blocked by
   6989             // <path-permission> above
   6990             if (allowDefaultRead) readMet = true;
   6991             if (allowDefaultWrite) writeMet = true;
   6992 
   6993         } catch (RemoteException e) {
   6994             return false;
   6995         }
   6996 
   6997         return readMet && writeMet;
   6998     }
   6999 
   7000     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
   7001         ProviderInfo pi = null;
   7002         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   7003         if (cpr != null) {
   7004             pi = cpr.info;
   7005         } else {
   7006             try {
   7007                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7008                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
   7009             } catch (RemoteException ex) {
   7010             }
   7011         }
   7012         return pi;
   7013     }
   7014 
   7015     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7016         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7017         if (targetUris != null) {
   7018             return targetUris.get(grantUri);
   7019         }
   7020         return null;
   7021     }
   7022 
   7023     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7024             String targetPkg, int targetUid, GrantUri grantUri) {
   7025         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7026         if (targetUris == null) {
   7027             targetUris = Maps.newArrayMap();
   7028             mGrantedUriPermissions.put(targetUid, targetUris);
   7029         }
   7030 
   7031         UriPermission perm = targetUris.get(grantUri);
   7032         if (perm == null) {
   7033             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7034             targetUris.put(grantUri, perm);
   7035         }
   7036 
   7037         return perm;
   7038     }
   7039 
   7040     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7041             final int modeFlags) {
   7042         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7043         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7044                 : UriPermission.STRENGTH_OWNED;
   7045 
   7046         // Root gets to do everything.
   7047         if (uid == 0) {
   7048             return true;
   7049         }
   7050 
   7051         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7052         if (perms == null) return false;
   7053 
   7054         // First look for exact match
   7055         final UriPermission exactPerm = perms.get(grantUri);
   7056         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7057             return true;
   7058         }
   7059 
   7060         // No exact match, look for prefixes
   7061         final int N = perms.size();
   7062         for (int i = 0; i < N; i++) {
   7063             final UriPermission perm = perms.valueAt(i);
   7064             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7065                     && perm.getStrength(modeFlags) >= minStrength) {
   7066                 return true;
   7067             }
   7068         }
   7069 
   7070         return false;
   7071     }
   7072 
   7073     /**
   7074      * @param uri This uri must NOT contain an embedded userId.
   7075      * @param userId The userId in which the uri is to be resolved.
   7076      */
   7077     @Override
   7078     public int checkUriPermission(Uri uri, int pid, int uid,
   7079             final int modeFlags, int userId, IBinder callerToken) {
   7080         enforceNotIsolatedCaller("checkUriPermission");
   7081 
   7082         // Another redirected-binder-call permissions check as in
   7083         // {@link checkPermissionWithToken}.
   7084         Identity tlsIdentity = sCallerIdentity.get();
   7085         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7086             uid = tlsIdentity.uid;
   7087             pid = tlsIdentity.pid;
   7088         }
   7089 
   7090         // Our own process gets to do everything.
   7091         if (pid == MY_PID) {
   7092             return PackageManager.PERMISSION_GRANTED;
   7093         }
   7094         synchronized (this) {
   7095             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   7096                     ? PackageManager.PERMISSION_GRANTED
   7097                     : PackageManager.PERMISSION_DENIED;
   7098         }
   7099     }
   7100 
   7101     /**
   7102      * Check if the targetPkg can be granted permission to access uri by
   7103      * the callingUid using the given modeFlags.  Throws a security exception
   7104      * if callingUid is not allowed to do this.  Returns the uid of the target
   7105      * if the URI permission grant should be performed; returns -1 if it is not
   7106      * needed (for example targetPkg already has permission to access the URI).
   7107      * If you already know the uid of the target, you can supply it in
   7108      * lastTargetUid else set that to -1.
   7109      */
   7110     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7111             final int modeFlags, int lastTargetUid) {
   7112         if (!Intent.isAccessUriMode(modeFlags)) {
   7113             return -1;
   7114         }
   7115 
   7116         if (targetPkg != null) {
   7117             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7118                     "Checking grant " + targetPkg + " permission to " + grantUri);
   7119         }
   7120 
   7121         final IPackageManager pm = AppGlobals.getPackageManager();
   7122 
   7123         // If this is not a content: uri, we can't do anything with it.
   7124         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   7125             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7126                     "Can't grant URI permission for non-content URI: " + grantUri);
   7127             return -1;
   7128         }
   7129 
   7130         final String authority = grantUri.uri.getAuthority();
   7131         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7132         if (pi == null) {
   7133             Slog.w(TAG, "No content provider found for permission check: " +
   7134                     grantUri.uri.toSafeString());
   7135             return -1;
   7136         }
   7137 
   7138         int targetUid = lastTargetUid;
   7139         if (targetUid < 0 && targetPkg != null) {
   7140             try {
   7141                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   7142                 if (targetUid < 0) {
   7143                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7144                             "Can't grant URI permission no uid for: " + targetPkg);
   7145                     return -1;
   7146                 }
   7147             } catch (RemoteException ex) {
   7148                 return -1;
   7149             }
   7150         }
   7151 
   7152         if (targetUid >= 0) {
   7153             // First...  does the target actually need this permission?
   7154             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   7155                 // No need to grant the target this permission.
   7156                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7157                         "Target " + targetPkg + " already has full permission to " + grantUri);
   7158                 return -1;
   7159             }
   7160         } else {
   7161             // First...  there is no target package, so can anyone access it?
   7162             boolean allowed = pi.exported;
   7163             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   7164                 if (pi.readPermission != null) {
   7165                     allowed = false;
   7166                 }
   7167             }
   7168             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   7169                 if (pi.writePermission != null) {
   7170                     allowed = false;
   7171                 }
   7172             }
   7173             if (allowed) {
   7174                 return -1;
   7175             }
   7176         }
   7177 
   7178         /* There is a special cross user grant if:
   7179          * - The target is on another user.
   7180          * - Apps on the current user can access the uri without any uid permissions.
   7181          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   7182          * grant uri permissions.
   7183          */
   7184         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   7185                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   7186                 modeFlags, false /*without considering the uid permissions*/);
   7187 
   7188         // Second...  is the provider allowing granting of URI permissions?
   7189         if (!specialCrossUserGrant) {
   7190             if (!pi.grantUriPermissions) {
   7191                 throw new SecurityException("Provider " + pi.packageName
   7192                         + "/" + pi.name
   7193                         + " does not allow granting of Uri permissions (uri "
   7194                         + grantUri + ")");
   7195             }
   7196             if (pi.uriPermissionPatterns != null) {
   7197                 final int N = pi.uriPermissionPatterns.length;
   7198                 boolean allowed = false;
   7199                 for (int i=0; i<N; i++) {
   7200                     if (pi.uriPermissionPatterns[i] != null
   7201                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   7202                         allowed = true;
   7203                         break;
   7204                     }
   7205                 }
   7206                 if (!allowed) {
   7207                     throw new SecurityException("Provider " + pi.packageName
   7208                             + "/" + pi.name
   7209                             + " does not allow granting of permission to path of Uri "
   7210                             + grantUri);
   7211                 }
   7212             }
   7213         }
   7214 
   7215         // Third...  does the caller itself have permission to access
   7216         // this uri?
   7217         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   7218             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7219                 // Require they hold a strong enough Uri permission
   7220                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   7221                     throw new SecurityException("Uid " + callingUid
   7222                             + " does not have permission to uri " + grantUri);
   7223                 }
   7224             }
   7225         }
   7226         return targetUid;
   7227     }
   7228 
   7229     /**
   7230      * @param uri This uri must NOT contain an embedded userId.
   7231      * @param userId The userId in which the uri is to be resolved.
   7232      */
   7233     @Override
   7234     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   7235             final int modeFlags, int userId) {
   7236         enforceNotIsolatedCaller("checkGrantUriPermission");
   7237         synchronized(this) {
   7238             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   7239                     new GrantUri(userId, uri, false), modeFlags, -1);
   7240         }
   7241     }
   7242 
   7243     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   7244             final int modeFlags, UriPermissionOwner owner) {
   7245         if (!Intent.isAccessUriMode(modeFlags)) {
   7246             return;
   7247         }
   7248 
   7249         // So here we are: the caller has the assumed permission
   7250         // to the uri, and the target doesn't.  Let's now give this to
   7251         // the target.
   7252 
   7253         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7254                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   7255 
   7256         final String authority = grantUri.uri.getAuthority();
   7257         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7258         if (pi == null) {
   7259             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   7260             return;
   7261         }
   7262 
   7263         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   7264             grantUri.prefix = true;
   7265         }
   7266         final UriPermission perm = findOrCreateUriPermissionLocked(
   7267                 pi.packageName, targetPkg, targetUid, grantUri);
   7268         perm.grantModes(modeFlags, owner);
   7269     }
   7270 
   7271     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7272             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   7273         if (targetPkg == null) {
   7274             throw new NullPointerException("targetPkg");
   7275         }
   7276         int targetUid;
   7277         final IPackageManager pm = AppGlobals.getPackageManager();
   7278         try {
   7279             targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7280         } catch (RemoteException ex) {
   7281             return;
   7282         }
   7283 
   7284         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   7285                 targetUid);
   7286         if (targetUid < 0) {
   7287             return;
   7288         }
   7289 
   7290         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   7291                 owner);
   7292     }
   7293 
   7294     static class NeededUriGrants extends ArrayList<GrantUri> {
   7295         final String targetPkg;
   7296         final int targetUid;
   7297         final int flags;
   7298 
   7299         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   7300             this.targetPkg = targetPkg;
   7301             this.targetUid = targetUid;
   7302             this.flags = flags;
   7303         }
   7304     }
   7305 
   7306     /**
   7307      * Like checkGrantUriPermissionLocked, but takes an Intent.
   7308      */
   7309     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   7310             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   7311         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7312                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   7313                 + " clip=" + (intent != null ? intent.getClipData() : null)
   7314                 + " from " + intent + "; flags=0x"
   7315                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   7316 
   7317         if (targetPkg == null) {
   7318             throw new NullPointerException("targetPkg");
   7319         }
   7320 
   7321         if (intent == null) {
   7322             return null;
   7323         }
   7324         Uri data = intent.getData();
   7325         ClipData clip = intent.getClipData();
   7326         if (data == null && clip == null) {
   7327             return null;
   7328         }
   7329         // Default userId for uris in the intent (if they don't specify it themselves)
   7330         int contentUserHint = intent.getContentUserHint();
   7331         if (contentUserHint == UserHandle.USER_CURRENT) {
   7332             contentUserHint = UserHandle.getUserId(callingUid);
   7333         }
   7334         final IPackageManager pm = AppGlobals.getPackageManager();
   7335         int targetUid;
   7336         if (needed != null) {
   7337             targetUid = needed.targetUid;
   7338         } else {
   7339             try {
   7340                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7341             } catch (RemoteException ex) {
   7342                 return null;
   7343             }
   7344             if (targetUid < 0) {
   7345                 if (DEBUG_URI_PERMISSION) {
   7346                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
   7347                             + " on user " + targetUserId);
   7348                 }
   7349                 return null;
   7350             }
   7351         }
   7352         if (data != null) {
   7353             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   7354             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7355                     targetUid);
   7356             if (targetUid > 0) {
   7357                 if (needed == null) {
   7358                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7359                 }
   7360                 needed.add(grantUri);
   7361             }
   7362         }
   7363         if (clip != null) {
   7364             for (int i=0; i<clip.getItemCount(); i++) {
   7365                 Uri uri = clip.getItemAt(i).getUri();
   7366                 if (uri != null) {
   7367                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   7368                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7369                             targetUid);
   7370                     if (targetUid > 0) {
   7371                         if (needed == null) {
   7372                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7373                         }
   7374                         needed.add(grantUri);
   7375                     }
   7376                 } else {
   7377                     Intent clipIntent = clip.getItemAt(i).getIntent();
   7378                     if (clipIntent != null) {
   7379                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   7380                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   7381                         if (newNeeded != null) {
   7382                             needed = newNeeded;
   7383                         }
   7384                     }
   7385                 }
   7386             }
   7387         }
   7388 
   7389         return needed;
   7390     }
   7391 
   7392     /**
   7393      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   7394      */
   7395     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   7396             UriPermissionOwner owner) {
   7397         if (needed != null) {
   7398             for (int i=0; i<needed.size(); i++) {
   7399                 GrantUri grantUri = needed.get(i);
   7400                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   7401                         grantUri, needed.flags, owner);
   7402             }
   7403         }
   7404     }
   7405 
   7406     void grantUriPermissionFromIntentLocked(int callingUid,
   7407             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   7408         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   7409                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   7410         if (needed == null) {
   7411             return;
   7412         }
   7413 
   7414         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   7415     }
   7416 
   7417     /**
   7418      * @param uri This uri must NOT contain an embedded userId.
   7419      * @param userId The userId in which the uri is to be resolved.
   7420      */
   7421     @Override
   7422     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   7423             final int modeFlags, int userId) {
   7424         enforceNotIsolatedCaller("grantUriPermission");
   7425         GrantUri grantUri = new GrantUri(userId, uri, false);
   7426         synchronized(this) {
   7427             final ProcessRecord r = getRecordForAppLocked(caller);
   7428             if (r == null) {
   7429                 throw new SecurityException("Unable to find app for caller "
   7430                         + caller
   7431                         + " when granting permission to uri " + grantUri);
   7432             }
   7433             if (targetPkg == null) {
   7434                 throw new IllegalArgumentException("null target");
   7435             }
   7436             if (grantUri == null) {
   7437                 throw new IllegalArgumentException("null uri");
   7438             }
   7439 
   7440             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   7441                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   7442                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   7443                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   7444 
   7445             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   7446                     UserHandle.getUserId(r.uid));
   7447         }
   7448     }
   7449 
   7450     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   7451         if (perm.modeFlags == 0) {
   7452             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   7453                     perm.targetUid);
   7454             if (perms != null) {
   7455                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7456                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   7457 
   7458                 perms.remove(perm.uri);
   7459                 if (perms.isEmpty()) {
   7460                     mGrantedUriPermissions.remove(perm.targetUid);
   7461                 }
   7462             }
   7463         }
   7464     }
   7465 
   7466     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   7467         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
   7468 
   7469         final IPackageManager pm = AppGlobals.getPackageManager();
   7470         final String authority = grantUri.uri.getAuthority();
   7471         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7472         if (pi == null) {
   7473             Slog.w(TAG, "No content provider found for permission revoke: "
   7474                     + grantUri.toSafeString());
   7475             return;
   7476         }
   7477 
   7478         // Does the caller have this permission on the URI?
   7479         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7480             // If they don't have direct access to the URI, then revoke any
   7481             // ownerless URI permissions that have been granted to them.
   7482             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   7483             if (perms != null) {
   7484                 boolean persistChanged = false;
   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, "Revoking non-owned " + perm.targetUid +
   7491                                     " permission to " + perm.uri);
   7492                         persistChanged |= perm.revokeModes(
   7493                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   7494                         if (perm.modeFlags == 0) {
   7495                             it.remove();
   7496                         }
   7497                     }
   7498                 }
   7499                 if (perms.isEmpty()) {
   7500                     mGrantedUriPermissions.remove(callingUid);
   7501                 }
   7502                 if (persistChanged) {
   7503                     schedulePersistUriGrants();
   7504                 }
   7505             }
   7506             return;
   7507         }
   7508 
   7509         boolean persistChanged = false;
   7510 
   7511         // Go through all of the permissions and remove any that match.
   7512         int N = mGrantedUriPermissions.size();
   7513         for (int i = 0; i < N; i++) {
   7514             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7515             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7516 
   7517             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7518                 final UriPermission perm = it.next();
   7519                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   7520                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   7521                     if (DEBUG_URI_PERMISSION)
   7522                         Slog.v(TAG,
   7523                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   7524                     persistChanged |= perm.revokeModes(
   7525                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7526                     if (perm.modeFlags == 0) {
   7527                         it.remove();
   7528                     }
   7529                 }
   7530             }
   7531 
   7532             if (perms.isEmpty()) {
   7533                 mGrantedUriPermissions.remove(targetUid);
   7534                 N--;
   7535                 i--;
   7536             }
   7537         }
   7538 
   7539         if (persistChanged) {
   7540             schedulePersistUriGrants();
   7541         }
   7542     }
   7543 
   7544     /**
   7545      * @param uri This uri must NOT contain an embedded userId.
   7546      * @param userId The userId in which the uri is to be resolved.
   7547      */
   7548     @Override
   7549     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   7550             int userId) {
   7551         enforceNotIsolatedCaller("revokeUriPermission");
   7552         synchronized(this) {
   7553             final ProcessRecord r = getRecordForAppLocked(caller);
   7554             if (r == null) {
   7555                 throw new SecurityException("Unable to find app for caller "
   7556                         + caller
   7557                         + " when revoking permission to uri " + uri);
   7558             }
   7559             if (uri == null) {
   7560                 Slog.w(TAG, "revokeUriPermission: null uri");
   7561                 return;
   7562             }
   7563 
   7564             if (!Intent.isAccessUriMode(modeFlags)) {
   7565                 return;
   7566             }
   7567 
   7568             final IPackageManager pm = AppGlobals.getPackageManager();
   7569             final String authority = uri.getAuthority();
   7570             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
   7571             if (pi == null) {
   7572                 Slog.w(TAG, "No content provider found for permission revoke: "
   7573                         + uri.toSafeString());
   7574                 return;
   7575             }
   7576 
   7577             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   7578         }
   7579     }
   7580 
   7581     /**
   7582      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   7583      * given package.
   7584      *
   7585      * @param packageName Package name to match, or {@code null} to apply to all
   7586      *            packages.
   7587      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   7588      *            to all users.
   7589      * @param persistable If persistable grants should be removed.
   7590      */
   7591     private void removeUriPermissionsForPackageLocked(
   7592             String packageName, int userHandle, boolean persistable) {
   7593         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   7594             throw new IllegalArgumentException("Must narrow by either package or user");
   7595         }
   7596 
   7597         boolean persistChanged = false;
   7598 
   7599         int N = mGrantedUriPermissions.size();
   7600         for (int i = 0; i < N; i++) {
   7601             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7602             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7603 
   7604             // Only inspect grants matching user
   7605             if (userHandle == UserHandle.USER_ALL
   7606                     || userHandle == UserHandle.getUserId(targetUid)) {
   7607                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7608                     final UriPermission perm = it.next();
   7609 
   7610                     // Only inspect grants matching package
   7611                     if (packageName == null || perm.sourcePkg.equals(packageName)
   7612                             || perm.targetPkg.equals(packageName)) {
   7613                         persistChanged |= perm.revokeModes(persistable
   7614                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7615 
   7616                         // Only remove when no modes remain; any persisted grants
   7617                         // will keep this alive.
   7618                         if (perm.modeFlags == 0) {
   7619                             it.remove();
   7620                         }
   7621                     }
   7622                 }
   7623 
   7624                 if (perms.isEmpty()) {
   7625                     mGrantedUriPermissions.remove(targetUid);
   7626                     N--;
   7627                     i--;
   7628                 }
   7629             }
   7630         }
   7631 
   7632         if (persistChanged) {
   7633             schedulePersistUriGrants();
   7634         }
   7635     }
   7636 
   7637     @Override
   7638     public IBinder newUriPermissionOwner(String name) {
   7639         enforceNotIsolatedCaller("newUriPermissionOwner");
   7640         synchronized(this) {
   7641             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   7642             return owner.getExternalTokenLocked();
   7643         }
   7644     }
   7645 
   7646     /**
   7647      * @param uri This uri must NOT contain an embedded userId.
   7648      * @param sourceUserId The userId in which the uri is to be resolved.
   7649      * @param targetUserId The userId of the app that receives the grant.
   7650      */
   7651     @Override
   7652     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   7653             final int modeFlags, int sourceUserId, int targetUserId) {
   7654         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   7655                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
   7656         synchronized(this) {
   7657             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7658             if (owner == null) {
   7659                 throw new IllegalArgumentException("Unknown owner: " + token);
   7660             }
   7661             if (fromUid != Binder.getCallingUid()) {
   7662                 if (Binder.getCallingUid() != Process.myUid()) {
   7663                     // Only system code can grant URI permissions on behalf
   7664                     // of other users.
   7665                     throw new SecurityException("nice try");
   7666                 }
   7667             }
   7668             if (targetPkg == null) {
   7669                 throw new IllegalArgumentException("null target");
   7670             }
   7671             if (uri == null) {
   7672                 throw new IllegalArgumentException("null uri");
   7673             }
   7674 
   7675             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   7676                     modeFlags, owner, targetUserId);
   7677         }
   7678     }
   7679 
   7680     /**
   7681      * @param uri This uri must NOT contain an embedded userId.
   7682      * @param userId The userId in which the uri is to be resolved.
   7683      */
   7684     @Override
   7685     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   7686         synchronized(this) {
   7687             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7688             if (owner == null) {
   7689                 throw new IllegalArgumentException("Unknown owner: " + token);
   7690             }
   7691 
   7692             if (uri == null) {
   7693                 owner.removeUriPermissionsLocked(mode);
   7694             } else {
   7695                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
   7696             }
   7697         }
   7698     }
   7699 
   7700     private void schedulePersistUriGrants() {
   7701         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   7702             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   7703                     10 * DateUtils.SECOND_IN_MILLIS);
   7704         }
   7705     }
   7706 
   7707     private void writeGrantedUriPermissions() {
   7708         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
   7709 
   7710         // Snapshot permissions so we can persist without lock
   7711         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   7712         synchronized (this) {
   7713             final int size = mGrantedUriPermissions.size();
   7714             for (int i = 0; i < size; i++) {
   7715                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7716                 for (UriPermission perm : perms.values()) {
   7717                     if (perm.persistedModeFlags != 0) {
   7718                         persist.add(perm.snapshot());
   7719                     }
   7720                 }
   7721             }
   7722         }
   7723 
   7724         FileOutputStream fos = null;
   7725         try {
   7726             fos = mGrantFile.startWrite();
   7727 
   7728             XmlSerializer out = new FastXmlSerializer();
   7729             out.setOutput(fos, "utf-8");
   7730             out.startDocument(null, true);
   7731             out.startTag(null, TAG_URI_GRANTS);
   7732             for (UriPermission.Snapshot perm : persist) {
   7733                 out.startTag(null, TAG_URI_GRANT);
   7734                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   7735                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   7736                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   7737                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   7738                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   7739                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   7740                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   7741                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   7742                 out.endTag(null, TAG_URI_GRANT);
   7743             }
   7744             out.endTag(null, TAG_URI_GRANTS);
   7745             out.endDocument();
   7746 
   7747             mGrantFile.finishWrite(fos);
   7748         } catch (IOException e) {
   7749             if (fos != null) {
   7750                 mGrantFile.failWrite(fos);
   7751             }
   7752         }
   7753     }
   7754 
   7755     private void readGrantedUriPermissionsLocked() {
   7756         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
   7757 
   7758         final long now = System.currentTimeMillis();
   7759 
   7760         FileInputStream fis = null;
   7761         try {
   7762             fis = mGrantFile.openRead();
   7763             final XmlPullParser in = Xml.newPullParser();
   7764             in.setInput(fis, null);
   7765 
   7766             int type;
   7767             while ((type = in.next()) != END_DOCUMENT) {
   7768                 final String tag = in.getName();
   7769                 if (type == START_TAG) {
   7770                     if (TAG_URI_GRANT.equals(tag)) {
   7771                         final int sourceUserId;
   7772                         final int targetUserId;
   7773                         final int userHandle = readIntAttribute(in,
   7774                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   7775                         if (userHandle != UserHandle.USER_NULL) {
   7776                             // For backwards compatibility.
   7777                             sourceUserId = userHandle;
   7778                             targetUserId = userHandle;
   7779                         } else {
   7780                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   7781                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   7782                         }
   7783                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   7784                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   7785                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   7786                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   7787                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   7788                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   7789 
   7790                         // Sanity check that provider still belongs to source package
   7791                         final ProviderInfo pi = getProviderInfoLocked(
   7792                                 uri.getAuthority(), sourceUserId);
   7793                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   7794                             int targetUid = -1;
   7795                             try {
   7796                                 targetUid = AppGlobals.getPackageManager()
   7797                                         .getPackageUid(targetPkg, targetUserId);
   7798                             } catch (RemoteException e) {
   7799                             }
   7800                             if (targetUid != -1) {
   7801                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   7802                                         sourcePkg, targetPkg, targetUid,
   7803                                         new GrantUri(sourceUserId, uri, prefix));
   7804                                 perm.initPersistedModes(modeFlags, createdTime);
   7805                             }
   7806                         } else {
   7807                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   7808                                     + " but instead found " + pi);
   7809                         }
   7810                     }
   7811                 }
   7812             }
   7813         } catch (FileNotFoundException e) {
   7814             // Missing grants is okay
   7815         } catch (IOException e) {
   7816             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7817         } catch (XmlPullParserException e) {
   7818             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7819         } finally {
   7820             IoUtils.closeQuietly(fis);
   7821         }
   7822     }
   7823 
   7824     /**
   7825      * @param uri This uri must NOT contain an embedded userId.
   7826      * @param userId The userId in which the uri is to be resolved.
   7827      */
   7828     @Override
   7829     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7830         enforceNotIsolatedCaller("takePersistableUriPermission");
   7831 
   7832         Preconditions.checkFlagsArgument(modeFlags,
   7833                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7834 
   7835         synchronized (this) {
   7836             final int callingUid = Binder.getCallingUid();
   7837             boolean persistChanged = false;
   7838             GrantUri grantUri = new GrantUri(userId, uri, false);
   7839 
   7840             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   7841                     new GrantUri(userId, uri, false));
   7842             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   7843                     new GrantUri(userId, uri, true));
   7844 
   7845             final boolean exactValid = (exactPerm != null)
   7846                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   7847             final boolean prefixValid = (prefixPerm != null)
   7848                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   7849 
   7850             if (!(exactValid || prefixValid)) {
   7851                 throw new SecurityException("No persistable permission grants found for UID "
   7852                         + callingUid + " and Uri " + grantUri.toSafeString());
   7853             }
   7854 
   7855             if (exactValid) {
   7856                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   7857             }
   7858             if (prefixValid) {
   7859                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   7860             }
   7861 
   7862             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   7863 
   7864             if (persistChanged) {
   7865                 schedulePersistUriGrants();
   7866             }
   7867         }
   7868     }
   7869 
   7870     /**
   7871      * @param uri This uri must NOT contain an embedded userId.
   7872      * @param userId The userId in which the uri is to be resolved.
   7873      */
   7874     @Override
   7875     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7876         enforceNotIsolatedCaller("releasePersistableUriPermission");
   7877 
   7878         Preconditions.checkFlagsArgument(modeFlags,
   7879                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7880 
   7881         synchronized (this) {
   7882             final int callingUid = Binder.getCallingUid();
   7883             boolean persistChanged = false;
   7884 
   7885             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   7886                     new GrantUri(userId, uri, false));
   7887             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   7888                     new GrantUri(userId, uri, true));
   7889             if (exactPerm == null && prefixPerm == null) {
   7890                 throw new SecurityException("No permission grants found for UID " + callingUid
   7891                         + " and Uri " + uri.toSafeString());
   7892             }
   7893 
   7894             if (exactPerm != null) {
   7895                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   7896                 removeUriPermissionIfNeededLocked(exactPerm);
   7897             }
   7898             if (prefixPerm != null) {
   7899                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   7900                 removeUriPermissionIfNeededLocked(prefixPerm);
   7901             }
   7902 
   7903             if (persistChanged) {
   7904                 schedulePersistUriGrants();
   7905             }
   7906         }
   7907     }
   7908 
   7909     /**
   7910      * Prune any older {@link UriPermission} for the given UID until outstanding
   7911      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   7912      *
   7913      * @return if any mutations occured that require persisting.
   7914      */
   7915     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   7916         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7917         if (perms == null) return false;
   7918         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   7919 
   7920         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   7921         for (UriPermission perm : perms.values()) {
   7922             if (perm.persistedModeFlags != 0) {
   7923                 persisted.add(perm);
   7924             }
   7925         }
   7926 
   7927         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   7928         if (trimCount <= 0) return false;
   7929 
   7930         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   7931         for (int i = 0; i < trimCount; i++) {
   7932             final UriPermission perm = persisted.get(i);
   7933 
   7934             if (DEBUG_URI_PERMISSION) {
   7935                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
   7936             }
   7937 
   7938             perm.releasePersistableModes(~0);
   7939             removeUriPermissionIfNeededLocked(perm);
   7940         }
   7941 
   7942         return true;
   7943     }
   7944 
   7945     @Override
   7946     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   7947             String packageName, boolean incoming) {
   7948         enforceNotIsolatedCaller("getPersistedUriPermissions");
   7949         Preconditions.checkNotNull(packageName, "packageName");
   7950 
   7951         final int callingUid = Binder.getCallingUid();
   7952         final IPackageManager pm = AppGlobals.getPackageManager();
   7953         try {
   7954             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
   7955             if (packageUid != callingUid) {
   7956                 throw new SecurityException(
   7957                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   7958             }
   7959         } catch (RemoteException e) {
   7960             throw new SecurityException("Failed to verify package name ownership");
   7961         }
   7962 
   7963         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   7964         synchronized (this) {
   7965             if (incoming) {
   7966                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   7967                         callingUid);
   7968                 if (perms == null) {
   7969                     Slog.w(TAG, "No permission grants found for " + packageName);
   7970                 } else {
   7971                     for (UriPermission perm : perms.values()) {
   7972                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   7973                             result.add(perm.buildPersistedPublicApiObject());
   7974                         }
   7975                     }
   7976                 }
   7977             } else {
   7978                 final int size = mGrantedUriPermissions.size();
   7979                 for (int i = 0; i < size; i++) {
   7980                     final ArrayMap<GrantUri, UriPermission> perms =
   7981                             mGrantedUriPermissions.valueAt(i);
   7982                     for (UriPermission perm : perms.values()) {
   7983                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   7984                             result.add(perm.buildPersistedPublicApiObject());
   7985                         }
   7986                     }
   7987                 }
   7988             }
   7989         }
   7990         return new ParceledListSlice<android.content.UriPermission>(result);
   7991     }
   7992 
   7993     @Override
   7994     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   7995         synchronized (this) {
   7996             ProcessRecord app =
   7997                 who != null ? getRecordForAppLocked(who) : null;
   7998             if (app == null) return;
   7999 
   8000             Message msg = Message.obtain();
   8001             msg.what = WAIT_FOR_DEBUGGER_MSG;
   8002             msg.obj = app;
   8003             msg.arg1 = waiting ? 1 : 0;
   8004             mHandler.sendMessage(msg);
   8005         }
   8006     }
   8007 
   8008     @Override
   8009     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8010         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8011         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8012         outInfo.availMem = Process.getFreeMemory();
   8013         outInfo.totalMem = Process.getTotalMemory();
   8014         outInfo.threshold = homeAppMem;
   8015         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   8016         outInfo.hiddenAppThreshold = cachedAppMem;
   8017         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   8018                 ProcessList.SERVICE_ADJ);
   8019         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   8020                 ProcessList.VISIBLE_APP_ADJ);
   8021         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   8022                 ProcessList.FOREGROUND_APP_ADJ);
   8023     }
   8024 
   8025     // =========================================================
   8026     // TASK MANAGEMENT
   8027     // =========================================================
   8028 
   8029     @Override
   8030     public List<IAppTask> getAppTasks(String callingPackage) {
   8031         int callingUid = Binder.getCallingUid();
   8032         long ident = Binder.clearCallingIdentity();
   8033 
   8034         synchronized(this) {
   8035             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   8036             try {
   8037                 if (localLOGV) Slog.v(TAG, "getAppTasks");
   8038 
   8039                 final int N = mRecentTasks.size();
   8040                 for (int i = 0; i < N; i++) {
   8041                     TaskRecord tr = mRecentTasks.get(i);
   8042                     // Skip tasks that do not match the caller.  We don't need to verify
   8043                     // callingPackage, because we are also limiting to callingUid and know
   8044                     // that will limit to the correct security sandbox.
   8045                     if (tr.effectiveUid != callingUid) {
   8046                         continue;
   8047                     }
   8048                     Intent intent = tr.getBaseIntent();
   8049                     if (intent == null ||
   8050                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   8051                         continue;
   8052                     }
   8053                     ActivityManager.RecentTaskInfo taskInfo =
   8054                             createRecentTaskInfoFromTaskRecord(tr);
   8055                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   8056                     list.add(taskImpl);
   8057                 }
   8058             } finally {
   8059                 Binder.restoreCallingIdentity(ident);
   8060             }
   8061             return list;
   8062         }
   8063     }
   8064 
   8065     @Override
   8066     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   8067         final int callingUid = Binder.getCallingUid();
   8068         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   8069 
   8070         synchronized(this) {
   8071             if (localLOGV) Slog.v(
   8072                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   8073 
   8074             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   8075                     callingUid);
   8076 
   8077             // TODO: Improve with MRU list from all ActivityStacks.
   8078             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   8079         }
   8080 
   8081         return list;
   8082     }
   8083 
   8084     /**
   8085      * Creates a new RecentTaskInfo from a TaskRecord.
   8086      */
   8087     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   8088         // Update the task description to reflect any changes in the task stack
   8089         tr.updateTaskDescription();
   8090 
   8091         // Compose the recent task info
   8092         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   8093         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   8094         rti.persistentId = tr.taskId;
   8095         rti.baseIntent = new Intent(tr.getBaseIntent());
   8096         rti.origActivity = tr.origActivity;
   8097         rti.description = tr.lastDescription;
   8098         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   8099         rti.userId = tr.userId;
   8100         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   8101         rti.firstActiveTime = tr.firstActiveTime;
   8102         rti.lastActiveTime = tr.lastActiveTime;
   8103         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   8104         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   8105         return rti;
   8106     }
   8107 
   8108     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   8109         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   8110                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   8111         if (!allowed) {
   8112             if (checkPermission(android.Manifest.permission.GET_TASKS,
   8113                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   8114                 // Temporary compatibility: some existing apps on the system image may
   8115                 // still be requesting the old permission and not switched to the new
   8116                 // one; if so, we'll still allow them full access.  This means we need
   8117                 // to see if they are holding the old permission and are a system app.
   8118                 try {
   8119                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   8120                         allowed = true;
   8121                         Slog.w(TAG, caller + ": caller " + callingUid
   8122                                 + " is using old GET_TASKS but privileged; allowing");
   8123                     }
   8124                 } catch (RemoteException e) {
   8125                 }
   8126             }
   8127         }
   8128         if (!allowed) {
   8129             Slog.w(TAG, caller + ": caller " + callingUid
   8130                     + " does not hold REAL_GET_TASKS; limiting output");
   8131         }
   8132         return allowed;
   8133     }
   8134 
   8135     @Override
   8136     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
   8137         final int callingUid = Binder.getCallingUid();
   8138         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   8139                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   8140 
   8141         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   8142         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   8143         synchronized (this) {
   8144             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   8145                     callingUid);
   8146             final boolean detailed = checkCallingPermission(
   8147                     android.Manifest.permission.GET_DETAILED_TASKS)
   8148                     == PackageManager.PERMISSION_GRANTED;
   8149 
   8150             final int N = mRecentTasks.size();
   8151             ArrayList<ActivityManager.RecentTaskInfo> res
   8152                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   8153                             maxNum < N ? maxNum : N);
   8154 
   8155             final Set<Integer> includedUsers;
   8156             if (includeProfiles) {
   8157                 includedUsers = getProfileIdsLocked(userId);
   8158             } else {
   8159                 includedUsers = new HashSet<Integer>();
   8160             }
   8161             includedUsers.add(Integer.valueOf(userId));
   8162 
   8163             for (int i=0; i<N && maxNum > 0; i++) {
   8164                 TaskRecord tr = mRecentTasks.get(i);
   8165                 // Only add calling user or related users recent tasks
   8166                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   8167                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
   8168                     continue;
   8169                 }
   8170 
   8171                 // Return the entry if desired by the caller.  We always return
   8172                 // the first entry, because callers always expect this to be the
   8173                 // foreground app.  We may filter others if the caller has
   8174                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   8175                 // we should exclude the entry.
   8176 
   8177                 if (i == 0
   8178                         || withExcluded
   8179                         || (tr.intent == null)
   8180                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   8181                                 == 0)) {
   8182                     if (!allowed) {
   8183                         // If the caller doesn't have the GET_TASKS permission, then only
   8184                         // allow them to see a small subset of tasks -- their own and home.
   8185                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   8186                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
   8187                             continue;
   8188                         }
   8189                     }
   8190                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   8191                         if (tr.stack != null && tr.stack.isHomeStack()) {
   8192                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
   8193                             continue;
   8194                         }
   8195                     }
   8196                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   8197                         // Don't include auto remove tasks that are finished or finishing.
   8198                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
   8199                                 + tr);
   8200                         continue;
   8201                     }
   8202                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   8203                             && !tr.isAvailable) {
   8204                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
   8205                         continue;
   8206                     }
   8207 
   8208                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   8209                     if (!detailed) {
   8210                         rti.baseIntent.replaceExtras((Bundle)null);
   8211                     }
   8212 
   8213                     res.add(rti);
   8214                     maxNum--;
   8215                 }
   8216             }
   8217             return res;
   8218         }
   8219     }
   8220 
   8221     TaskRecord recentTaskForIdLocked(int id) {
   8222         final int N = mRecentTasks.size();
   8223             for (int i=0; i<N; i++) {
   8224                 TaskRecord tr = mRecentTasks.get(i);
   8225                 if (tr.taskId == id) {
   8226                     return tr;
   8227                 }
   8228             }
   8229             return null;
   8230     }
   8231 
   8232     @Override
   8233     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   8234         synchronized (this) {
   8235             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   8236                     "getTaskThumbnail()");
   8237             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
   8238             if (tr != null) {
   8239                 return tr.getTaskThumbnailLocked();
   8240             }
   8241         }
   8242         return null;
   8243     }
   8244 
   8245     @Override
   8246     public int addAppTask(IBinder activityToken, Intent intent,
   8247             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   8248         final int callingUid = Binder.getCallingUid();
   8249         final long callingIdent = Binder.clearCallingIdentity();
   8250 
   8251         try {
   8252             synchronized (this) {
   8253                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8254                 if (r == null) {
   8255                     throw new IllegalArgumentException("Activity does not exist; token="
   8256                             + activityToken);
   8257                 }
   8258                 ComponentName comp = intent.getComponent();
   8259                 if (comp == null) {
   8260                     throw new IllegalArgumentException("Intent " + intent
   8261                             + " must specify explicit component");
   8262                 }
   8263                 if (thumbnail.getWidth() != mThumbnailWidth
   8264                         || thumbnail.getHeight() != mThumbnailHeight) {
   8265                     throw new IllegalArgumentException("Bad thumbnail size: got "
   8266                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   8267                             + mThumbnailWidth + "x" + mThumbnailHeight);
   8268                 }
   8269                 if (intent.getSelector() != null) {
   8270                     intent.setSelector(null);
   8271                 }
   8272                 if (intent.getSourceBounds() != null) {
   8273                     intent.setSourceBounds(null);
   8274                 }
   8275                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   8276                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   8277                         // The caller has added this as an auto-remove task...  that makes no
   8278                         // sense, so turn off auto-remove.
   8279                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   8280                     }
   8281                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   8282                     // Must be a new task.
   8283                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8284                 }
   8285                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   8286                     mLastAddedTaskActivity = null;
   8287                 }
   8288                 ActivityInfo ainfo = mLastAddedTaskActivity;
   8289                 if (ainfo == null) {
   8290                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   8291                             comp, 0, UserHandle.getUserId(callingUid));
   8292                     if (ainfo.applicationInfo.uid != callingUid) {
   8293                         throw new SecurityException(
   8294                                 "Can't add task for another application: target uid="
   8295                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   8296                     }
   8297                 }
   8298 
   8299                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
   8300                         intent, description);
   8301 
   8302                 int trimIdx = trimRecentsForTaskLocked(task, false);
   8303                 if (trimIdx >= 0) {
   8304                     // If this would have caused a trim, then we'll abort because that
   8305                     // means it would be added at the end of the list but then just removed.
   8306                     return INVALID_TASK_ID;
   8307                 }
   8308 
   8309                 final int N = mRecentTasks.size();
   8310                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   8311                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   8312                     tr.removedFromRecents();
   8313                 }
   8314 
   8315                 task.inRecents = true;
   8316                 mRecentTasks.add(task);
   8317                 r.task.stack.addTask(task, false, false);
   8318 
   8319                 task.setLastThumbnail(thumbnail);
   8320                 task.freeLastThumbnail();
   8321 
   8322                 return task.taskId;
   8323             }
   8324         } finally {
   8325             Binder.restoreCallingIdentity(callingIdent);
   8326         }
   8327     }
   8328 
   8329     @Override
   8330     public Point getAppTaskThumbnailSize() {
   8331         synchronized (this) {
   8332             return new Point(mThumbnailWidth,  mThumbnailHeight);
   8333         }
   8334     }
   8335 
   8336     @Override
   8337     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   8338         synchronized (this) {
   8339             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8340             if (r != null) {
   8341                 r.setTaskDescription(td);
   8342                 r.task.updateTaskDescription();
   8343             }
   8344         }
   8345     }
   8346 
   8347     @Override
   8348     public Bitmap getTaskDescriptionIcon(String filename) {
   8349         if (!FileUtils.isValidExtFilename(filename)
   8350                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   8351             throw new IllegalArgumentException("Bad filename: " + filename);
   8352         }
   8353         return mTaskPersister.getTaskDescriptionIcon(filename);
   8354     }
   8355 
   8356     @Override
   8357     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
   8358             throws RemoteException {
   8359         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   8360                 opts.getCustomInPlaceResId() == 0) {
   8361             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   8362                     "with valid animation");
   8363         }
   8364         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
   8365         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
   8366                 opts.getCustomInPlaceResId());
   8367         mWindowManager.executeAppTransition();
   8368     }
   8369 
   8370     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
   8371         mRecentTasks.remove(tr);
   8372         tr.removedFromRecents();
   8373         ComponentName component = tr.getBaseIntent().getComponent();
   8374         if (component == null) {
   8375             Slog.w(TAG, "No component for base intent of task: " + tr);
   8376             return;
   8377         }
   8378 
   8379         if (!killProcess) {
   8380             return;
   8381         }
   8382 
   8383         // Determine if the process(es) for this task should be killed.
   8384         final String pkg = component.getPackageName();
   8385         ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
   8386         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   8387         for (int i = 0; i < pmap.size(); i++) {
   8388 
   8389             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   8390             for (int j = 0; j < uids.size(); j++) {
   8391                 ProcessRecord proc = uids.valueAt(j);
   8392                 if (proc.userId != tr.userId) {
   8393                     // Don't kill process for a different user.
   8394                     continue;
   8395                 }
   8396                 if (proc == mHomeProcess) {
   8397                     // Don't kill the home process along with tasks from the same package.
   8398                     continue;
   8399                 }
   8400                 if (!proc.pkgList.containsKey(pkg)) {
   8401                     // Don't kill process that is not associated with this task.
   8402                     continue;
   8403                 }
   8404 
   8405                 for (int k = 0; k < proc.activities.size(); k++) {
   8406                     TaskRecord otherTask = proc.activities.get(k).task;
   8407                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   8408                         // Don't kill process(es) that has an activity in a different task that is
   8409                         // also in recents.
   8410                         return;
   8411                     }
   8412                 }
   8413 
   8414                 // Add process to kill list.
   8415                 procsToKill.add(proc);
   8416             }
   8417         }
   8418 
   8419         // Find any running services associated with this app and stop if needed.
   8420         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   8421 
   8422         // Kill the running processes.
   8423         for (int i = 0; i < procsToKill.size(); i++) {
   8424             ProcessRecord pr = procsToKill.get(i);
   8425             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   8426                 pr.kill("remove task", true);
   8427             } else {
   8428                 pr.waitingToKill = "remove task";
   8429             }
   8430         }
   8431     }
   8432 
   8433     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   8434         // Remove all tasks with activities in the specified package from the list of recent tasks
   8435         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   8436             TaskRecord tr = mRecentTasks.get(i);
   8437             if (tr.userId != userId) continue;
   8438 
   8439             ComponentName cn = tr.intent.getComponent();
   8440             if (cn != null && cn.getPackageName().equals(packageName)) {
   8441                 // If the package name matches, remove the task.
   8442                 removeTaskByIdLocked(tr.taskId, true);
   8443             }
   8444         }
   8445     }
   8446 
   8447     private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
   8448         final IPackageManager pm = AppGlobals.getPackageManager();
   8449         final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
   8450 
   8451         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   8452             TaskRecord tr = mRecentTasks.get(i);
   8453             if (tr.userId != userId) continue;
   8454 
   8455             ComponentName cn = tr.intent.getComponent();
   8456             if (cn != null && cn.getPackageName().equals(packageName)) {
   8457                 // Skip if component still exists in the package.
   8458                 if (componentsKnownToExist.contains(cn)) continue;
   8459 
   8460                 try {
   8461                     ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
   8462                     if (info != null) {
   8463                         componentsKnownToExist.add(cn);
   8464                     } else {
   8465                         removeTaskByIdLocked(tr.taskId, false);
   8466                     }
   8467                 } catch (RemoteException e) {
   8468                     Log.e(TAG, "Activity info query failed. component=" + cn, e);
   8469                 }
   8470             }
   8471         }
   8472     }
   8473 
   8474     /**
   8475      * Removes the task with the specified task id.
   8476      *
   8477      * @param taskId Identifier of the task to be removed.
   8478      * @param killProcess Kill any process associated with the task if possible.
   8479      * @return Returns true if the given task was found and removed.
   8480      */
   8481     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
   8482         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8483         if (tr != null) {
   8484             tr.removeTaskActivitiesLocked();
   8485             cleanUpRemovedTaskLocked(tr, killProcess);
   8486             if (tr.isPersistable) {
   8487                 notifyTaskPersisterLocked(null, true);
   8488             }
   8489             return true;
   8490         }
   8491         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   8492         return false;
   8493     }
   8494 
   8495     @Override
   8496     public boolean removeTask(int taskId) {
   8497         synchronized (this) {
   8498             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   8499                     "removeTask()");
   8500             long ident = Binder.clearCallingIdentity();
   8501             try {
   8502                 return removeTaskByIdLocked(taskId, true);
   8503             } finally {
   8504                 Binder.restoreCallingIdentity(ident);
   8505             }
   8506         }
   8507     }
   8508 
   8509     /**
   8510      * TODO: Add mController hook
   8511      */
   8512     @Override
   8513     public void moveTaskToFront(int taskId, int flags, Bundle options) {
   8514         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8515                 "moveTaskToFront()");
   8516 
   8517         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
   8518         synchronized(this) {
   8519             moveTaskToFrontLocked(taskId, flags, options);
   8520         }
   8521     }
   8522 
   8523     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
   8524         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8525                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   8526             ActivityOptions.abort(options);
   8527             return;
   8528         }
   8529         final long origId = Binder.clearCallingIdentity();
   8530         try {
   8531             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8532             if (task == null) {
   8533                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   8534                 return;
   8535             }
   8536             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   8537                 mStackSupervisor.showLockTaskToast();
   8538                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   8539                 return;
   8540             }
   8541             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   8542             if (prev != null && prev.isRecentsActivity()) {
   8543                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   8544             }
   8545             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
   8546         } finally {
   8547             Binder.restoreCallingIdentity(origId);
   8548         }
   8549         ActivityOptions.abort(options);
   8550     }
   8551 
   8552     @Override
   8553     public void moveTaskToBack(int taskId) {
   8554         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8555                 "moveTaskToBack()");
   8556 
   8557         synchronized(this) {
   8558             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8559             if (tr != null) {
   8560                 if (tr == mStackSupervisor.mLockTaskModeTask) {
   8561                     mStackSupervisor.showLockTaskToast();
   8562                     return;
   8563                 }
   8564                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
   8565                 ActivityStack stack = tr.stack;
   8566                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
   8567                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8568                             Binder.getCallingUid(), -1, -1, "Task to back")) {
   8569                         return;
   8570                     }
   8571                 }
   8572                 final long origId = Binder.clearCallingIdentity();
   8573                 try {
   8574                     stack.moveTaskToBackLocked(taskId);
   8575                 } finally {
   8576                     Binder.restoreCallingIdentity(origId);
   8577                 }
   8578             }
   8579         }
   8580     }
   8581 
   8582     /**
   8583      * Moves an activity, and all of the other activities within the same task, to the bottom
   8584      * of the history stack.  The activity's order within the task is unchanged.
   8585      *
   8586      * @param token A reference to the activity we wish to move
   8587      * @param nonRoot If false then this only works if the activity is the root
   8588      *                of a task; if true it will work for any activity in a task.
   8589      * @return Returns true if the move completed, false if not.
   8590      */
   8591     @Override
   8592     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   8593         enforceNotIsolatedCaller("moveActivityTaskToBack");
   8594         synchronized(this) {
   8595             final long origId = Binder.clearCallingIdentity();
   8596             try {
   8597                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   8598                 if (taskId >= 0) {
   8599                     if ((mStackSupervisor.mLockTaskModeTask != null)
   8600                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
   8601                         mStackSupervisor.showLockTaskToast();
   8602                         return false;
   8603                     }
   8604                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   8605                 }
   8606             } finally {
   8607                 Binder.restoreCallingIdentity(origId);
   8608             }
   8609         }
   8610         return false;
   8611     }
   8612 
   8613     @Override
   8614     public void moveTaskBackwards(int task) {
   8615         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8616                 "moveTaskBackwards()");
   8617 
   8618         synchronized(this) {
   8619             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8620                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   8621                 return;
   8622             }
   8623             final long origId = Binder.clearCallingIdentity();
   8624             moveTaskBackwardsLocked(task);
   8625             Binder.restoreCallingIdentity(origId);
   8626         }
   8627     }
   8628 
   8629     private final void moveTaskBackwardsLocked(int task) {
   8630         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   8631     }
   8632 
   8633     @Override
   8634     public IBinder getHomeActivityToken() throws RemoteException {
   8635         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8636                 "getHomeActivityToken()");
   8637         synchronized (this) {
   8638             return mStackSupervisor.getHomeActivityToken();
   8639         }
   8640     }
   8641 
   8642     @Override
   8643     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
   8644             IActivityContainerCallback callback) throws RemoteException {
   8645         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8646                 "createActivityContainer()");
   8647         synchronized (this) {
   8648             if (parentActivityToken == null) {
   8649                 throw new IllegalArgumentException("parent token must not be null");
   8650             }
   8651             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
   8652             if (r == null) {
   8653                 return null;
   8654             }
   8655             if (callback == null) {
   8656                 throw new IllegalArgumentException("callback must not be null");
   8657             }
   8658             return mStackSupervisor.createActivityContainer(r, callback);
   8659         }
   8660     }
   8661 
   8662     @Override
   8663     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   8664         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8665                 "deleteActivityContainer()");
   8666         synchronized (this) {
   8667             mStackSupervisor.deleteActivityContainer(container);
   8668         }
   8669     }
   8670 
   8671     @Override
   8672     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   8673         synchronized (this) {
   8674             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   8675             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   8676                 return stack.mActivityContainer.getDisplayId();
   8677             }
   8678             return Display.DEFAULT_DISPLAY;
   8679         }
   8680     }
   8681 
   8682     @Override
   8683     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   8684         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8685                 "moveTaskToStack()");
   8686         if (stackId == HOME_STACK_ID) {
   8687             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
   8688                     new RuntimeException("here").fillInStackTrace());
   8689         }
   8690         synchronized (this) {
   8691             long ident = Binder.clearCallingIdentity();
   8692             try {
   8693                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
   8694                         + stackId + " toTop=" + toTop);
   8695                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
   8696             } finally {
   8697                 Binder.restoreCallingIdentity(ident);
   8698             }
   8699         }
   8700     }
   8701 
   8702     @Override
   8703     public void resizeStack(int stackBoxId, Rect bounds) {
   8704         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8705                 "resizeStackBox()");
   8706         long ident = Binder.clearCallingIdentity();
   8707         try {
   8708             mWindowManager.resizeStack(stackBoxId, bounds);
   8709         } finally {
   8710             Binder.restoreCallingIdentity(ident);
   8711         }
   8712     }
   8713 
   8714     @Override
   8715     public List<StackInfo> getAllStackInfos() {
   8716         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8717                 "getAllStackInfos()");
   8718         long ident = Binder.clearCallingIdentity();
   8719         try {
   8720             synchronized (this) {
   8721                 return mStackSupervisor.getAllStackInfosLocked();
   8722             }
   8723         } finally {
   8724             Binder.restoreCallingIdentity(ident);
   8725         }
   8726     }
   8727 
   8728     @Override
   8729     public StackInfo getStackInfo(int stackId) {
   8730         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8731                 "getStackInfo()");
   8732         long ident = Binder.clearCallingIdentity();
   8733         try {
   8734             synchronized (this) {
   8735                 return mStackSupervisor.getStackInfoLocked(stackId);
   8736             }
   8737         } finally {
   8738             Binder.restoreCallingIdentity(ident);
   8739         }
   8740     }
   8741 
   8742     @Override
   8743     public boolean isInHomeStack(int taskId) {
   8744         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8745                 "getStackInfo()");
   8746         long ident = Binder.clearCallingIdentity();
   8747         try {
   8748             synchronized (this) {
   8749                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8750                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   8751             }
   8752         } finally {
   8753             Binder.restoreCallingIdentity(ident);
   8754         }
   8755     }
   8756 
   8757     @Override
   8758     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   8759         synchronized(this) {
   8760             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   8761         }
   8762     }
   8763 
   8764     private boolean isLockTaskAuthorized(String pkg) {
   8765         final DevicePolicyManager dpm = (DevicePolicyManager)
   8766                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
   8767         try {
   8768             int uid = mContext.getPackageManager().getPackageUid(pkg,
   8769                     Binder.getCallingUserHandle().getIdentifier());
   8770             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
   8771         } catch (NameNotFoundException e) {
   8772             return false;
   8773         }
   8774     }
   8775 
   8776     void startLockTaskMode(TaskRecord task) {
   8777         final String pkg;
   8778         synchronized (this) {
   8779             pkg = task.intent.getComponent().getPackageName();
   8780         }
   8781         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
   8782         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
   8783             StatusBarManagerInternal statusBarManager = LocalServices.getService(
   8784                     StatusBarManagerInternal.class);
   8785             if (statusBarManager != null) {
   8786                 statusBarManager.showScreenPinningRequest();
   8787             }
   8788             return;
   8789         }
   8790         long ident = Binder.clearCallingIdentity();
   8791         try {
   8792             synchronized (this) {
   8793                 // Since we lost lock on task, make sure it is still there.
   8794                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
   8795                 if (task != null) {
   8796                     if (!isSystemInitiated
   8797                             && ((mStackSupervisor.getFocusedStack() == null)
   8798                                     || (task != mStackSupervisor.getFocusedStack().topTask()))) {
   8799                         throw new IllegalArgumentException("Invalid task, not in foreground");
   8800                     }
   8801                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
   8802                             "startLockTask");
   8803                 }
   8804             }
   8805         } finally {
   8806             Binder.restoreCallingIdentity(ident);
   8807         }
   8808     }
   8809 
   8810     @Override
   8811     public void startLockTaskMode(int taskId) {
   8812         final TaskRecord task;
   8813         long ident = Binder.clearCallingIdentity();
   8814         try {
   8815             synchronized (this) {
   8816                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8817             }
   8818         } finally {
   8819             Binder.restoreCallingIdentity(ident);
   8820         }
   8821         if (task != null) {
   8822             startLockTaskMode(task);
   8823         }
   8824     }
   8825 
   8826     @Override
   8827     public void startLockTaskMode(IBinder token) {
   8828         final TaskRecord task;
   8829         long ident = Binder.clearCallingIdentity();
   8830         try {
   8831             synchronized (this) {
   8832                 final ActivityRecord r = ActivityRecord.forToken(token);
   8833                 if (r == null) {
   8834                     return;
   8835                 }
   8836                 task = r.task;
   8837             }
   8838         } finally {
   8839             Binder.restoreCallingIdentity(ident);
   8840         }
   8841         if (task != null) {
   8842             startLockTaskMode(task);
   8843         }
   8844     }
   8845 
   8846     @Override
   8847     public void startLockTaskModeOnCurrent() throws RemoteException {
   8848         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8849                 "startLockTaskModeOnCurrent");
   8850         long ident = Binder.clearCallingIdentity();
   8851         try {
   8852             ActivityRecord r = null;
   8853             synchronized (this) {
   8854                 r = mStackSupervisor.topRunningActivityLocked();
   8855             }
   8856             startLockTaskMode(r.task);
   8857         } finally {
   8858             Binder.restoreCallingIdentity(ident);
   8859         }
   8860     }
   8861 
   8862     @Override
   8863     public void stopLockTaskMode() {
   8864         // Verify that the user matches the package of the intent for the TaskRecord
   8865         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
   8866         // and stopLockTaskMode.
   8867         final int callingUid = Binder.getCallingUid();
   8868         if (callingUid != Process.SYSTEM_UID) {
   8869             try {
   8870                 String pkg =
   8871                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
   8872                 int uid = mContext.getPackageManager().getPackageUid(pkg,
   8873                         Binder.getCallingUserHandle().getIdentifier());
   8874                 if (uid != callingUid) {
   8875                     throw new SecurityException("Invalid uid, expected " + uid);
   8876                 }
   8877             } catch (NameNotFoundException e) {
   8878                 Log.d(TAG, "stopLockTaskMode " + e);
   8879                 return;
   8880             }
   8881         }
   8882         long ident = Binder.clearCallingIdentity();
   8883         try {
   8884             Log.d(TAG, "stopLockTaskMode");
   8885             // Stop lock task
   8886             synchronized (this) {
   8887                 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
   8888             }
   8889         } finally {
   8890             Binder.restoreCallingIdentity(ident);
   8891         }
   8892     }
   8893 
   8894     @Override
   8895     public void stopLockTaskModeOnCurrent() throws RemoteException {
   8896         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8897                 "stopLockTaskModeOnCurrent");
   8898         long ident = Binder.clearCallingIdentity();
   8899         try {
   8900             stopLockTaskMode();
   8901         } finally {
   8902             Binder.restoreCallingIdentity(ident);
   8903         }
   8904     }
   8905 
   8906     @Override
   8907     public boolean isInLockTaskMode() {
   8908         synchronized (this) {
   8909             return mStackSupervisor.isInLockTaskMode();
   8910         }
   8911     }
   8912 
   8913     // =========================================================
   8914     // CONTENT PROVIDERS
   8915     // =========================================================
   8916 
   8917     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   8918         List<ProviderInfo> providers = null;
   8919         try {
   8920             providers = AppGlobals.getPackageManager().
   8921                 queryContentProviders(app.processName, app.uid,
   8922                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   8923         } catch (RemoteException ex) {
   8924         }
   8925         if (DEBUG_MU)
   8926             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   8927         int userId = app.userId;
   8928         if (providers != null) {
   8929             int N = providers.size();
   8930             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   8931             for (int i=0; i<N; i++) {
   8932                 ProviderInfo cpi =
   8933                     (ProviderInfo)providers.get(i);
   8934                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   8935                         cpi.name, cpi.flags);
   8936                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   8937                     // This is a singleton provider, but a user besides the
   8938                     // default user is asking to initialize a process it runs
   8939                     // in...  well, no, it doesn't actually run in this process,
   8940                     // it runs in the process of the default user.  Get rid of it.
   8941                     providers.remove(i);
   8942                     N--;
   8943                     i--;
   8944                     continue;
   8945                 }
   8946 
   8947                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   8948                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   8949                 if (cpr == null) {
   8950                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   8951                     mProviderMap.putProviderByClass(comp, cpr);
   8952                 }
   8953                 if (DEBUG_MU)
   8954                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   8955                 app.pubProviders.put(cpi.name, cpr);
   8956                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   8957                     // Don't add this if it is a platform component that is marked
   8958                     // to run in multiple processes, because this is actually
   8959                     // part of the framework so doesn't make sense to track as a
   8960                     // separate apk in the process.
   8961                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   8962                             mProcessStats);
   8963                 }
   8964                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   8965             }
   8966         }
   8967         return providers;
   8968     }
   8969 
   8970     /**
   8971      * Check if {@link ProcessRecord} has a possible chance at accessing the
   8972      * given {@link ProviderInfo}. Final permission checking is always done
   8973      * in {@link ContentProvider}.
   8974      */
   8975     private final String checkContentProviderPermissionLocked(
   8976             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   8977         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   8978         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   8979         boolean checkedGrants = false;
   8980         if (checkUser) {
   8981             // Looking for cross-user grants before enforcing the typical cross-users permissions
   8982             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
   8983             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   8984                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   8985                     return null;
   8986                 }
   8987                 checkedGrants = true;
   8988             }
   8989             userId = handleIncomingUser(callingPid, callingUid, userId,
   8990                     false, ALLOW_NON_FULL,
   8991                     "checkContentProviderPermissionLocked " + cpi.authority, null);
   8992             if (userId != tmpTargetUserId) {
   8993                 // When we actually went to determine the final targer user ID, this ended
   8994                 // up different than our initial check for the authority.  This is because
   8995                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   8996                 // SELF.  So we need to re-check the grants again.
   8997                 checkedGrants = false;
   8998             }
   8999         }
   9000         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   9001                 cpi.applicationInfo.uid, cpi.exported)
   9002                 == PackageManager.PERMISSION_GRANTED) {
   9003             return null;
   9004         }
   9005         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   9006                 cpi.applicationInfo.uid, cpi.exported)
   9007                 == PackageManager.PERMISSION_GRANTED) {
   9008             return null;
   9009         }
   9010 
   9011         PathPermission[] pps = cpi.pathPermissions;
   9012         if (pps != null) {
   9013             int i = pps.length;
   9014             while (i > 0) {
   9015                 i--;
   9016                 PathPermission pp = pps[i];
   9017                 String pprperm = pp.getReadPermission();
   9018                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   9019                         cpi.applicationInfo.uid, cpi.exported)
   9020                         == PackageManager.PERMISSION_GRANTED) {
   9021                     return null;
   9022                 }
   9023                 String ppwperm = pp.getWritePermission();
   9024                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   9025                         cpi.applicationInfo.uid, cpi.exported)
   9026                         == PackageManager.PERMISSION_GRANTED) {
   9027                     return null;
   9028                 }
   9029             }
   9030         }
   9031         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   9032             return null;
   9033         }
   9034 
   9035         String msg;
   9036         if (!cpi.exported) {
   9037             msg = "Permission Denial: opening provider " + cpi.name
   9038                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9039                     + ", uid=" + callingUid + ") that is not exported from uid "
   9040                     + cpi.applicationInfo.uid;
   9041         } else {
   9042             msg = "Permission Denial: opening provider " + cpi.name
   9043                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9044                     + ", uid=" + callingUid + ") requires "
   9045                     + cpi.readPermission + " or " + cpi.writePermission;
   9046         }
   9047         Slog.w(TAG, msg);
   9048         return msg;
   9049     }
   9050 
   9051     /**
   9052      * Returns if the ContentProvider has granted a uri to callingUid
   9053      */
   9054     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   9055         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   9056         if (perms != null) {
   9057             for (int i=perms.size()-1; i>=0; i--) {
   9058                 GrantUri grantUri = perms.keyAt(i);
   9059                 if (grantUri.sourceUserId == userId || !checkUser) {
   9060                     if (matchesProvider(grantUri.uri, cpi)) {
   9061                         return true;
   9062                     }
   9063                 }
   9064             }
   9065         }
   9066         return false;
   9067     }
   9068 
   9069     /**
   9070      * Returns true if the uri authority is one of the authorities specified in the provider.
   9071      */
   9072     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   9073         String uriAuth = uri.getAuthority();
   9074         String cpiAuth = cpi.authority;
   9075         if (cpiAuth.indexOf(';') == -1) {
   9076             return cpiAuth.equals(uriAuth);
   9077         }
   9078         String[] cpiAuths = cpiAuth.split(";");
   9079         int length = cpiAuths.length;
   9080         for (int i = 0; i < length; i++) {
   9081             if (cpiAuths[i].equals(uriAuth)) return true;
   9082         }
   9083         return false;
   9084     }
   9085 
   9086     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   9087             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9088         if (r != null) {
   9089             for (int i=0; i<r.conProviders.size(); i++) {
   9090                 ContentProviderConnection conn = r.conProviders.get(i);
   9091                 if (conn.provider == cpr) {
   9092                     if (DEBUG_PROVIDER) Slog.v(TAG,
   9093                             "Adding provider requested by "
   9094                             + r.processName + " from process "
   9095                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9096                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9097                     if (stable) {
   9098                         conn.stableCount++;
   9099                         conn.numStableIncs++;
   9100                     } else {
   9101                         conn.unstableCount++;
   9102                         conn.numUnstableIncs++;
   9103                     }
   9104                     return conn;
   9105                 }
   9106             }
   9107             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   9108             if (stable) {
   9109                 conn.stableCount = 1;
   9110                 conn.numStableIncs = 1;
   9111             } else {
   9112                 conn.unstableCount = 1;
   9113                 conn.numUnstableIncs = 1;
   9114             }
   9115             cpr.connections.add(conn);
   9116             r.conProviders.add(conn);
   9117             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
   9118             return conn;
   9119         }
   9120         cpr.addExternalProcessHandleLocked(externalProcessToken);
   9121         return null;
   9122     }
   9123 
   9124     boolean decProviderCountLocked(ContentProviderConnection conn,
   9125             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9126         if (conn != null) {
   9127             cpr = conn.provider;
   9128             if (DEBUG_PROVIDER) Slog.v(TAG,
   9129                     "Removing provider requested by "
   9130                     + conn.client.processName + " from process "
   9131                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9132                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9133             if (stable) {
   9134                 conn.stableCount--;
   9135             } else {
   9136                 conn.unstableCount--;
   9137             }
   9138             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   9139                 cpr.connections.remove(conn);
   9140                 conn.client.conProviders.remove(conn);
   9141                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   9142                 return true;
   9143             }
   9144             return false;
   9145         }
   9146         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   9147         return false;
   9148     }
   9149 
   9150     private void checkTime(long startTime, String where) {
   9151         long now = SystemClock.elapsedRealtime();
   9152         if ((now-startTime) > 1000) {
   9153             // If we are taking more than a second, log about it.
   9154             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   9155         }
   9156     }
   9157 
   9158     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   9159             String name, IBinder token, boolean stable, int userId) {
   9160         ContentProviderRecord cpr;
   9161         ContentProviderConnection conn = null;
   9162         ProviderInfo cpi = null;
   9163 
   9164         synchronized(this) {
   9165             long startTime = SystemClock.elapsedRealtime();
   9166 
   9167             ProcessRecord r = null;
   9168             if (caller != null) {
   9169                 r = getRecordForAppLocked(caller);
   9170                 if (r == null) {
   9171                     throw new SecurityException(
   9172                             "Unable to find app for caller " + caller
   9173                           + " (pid=" + Binder.getCallingPid()
   9174                           + ") when getting content provider " + name);
   9175                 }
   9176             }
   9177 
   9178             boolean checkCrossUser = true;
   9179 
   9180             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   9181 
   9182             // First check if this content provider has been published...
   9183             cpr = mProviderMap.getProviderByName(name, userId);
   9184             // If that didn't work, check if it exists for user 0 and then
   9185             // verify that it's a singleton provider before using it.
   9186             if (cpr == null && userId != UserHandle.USER_OWNER) {
   9187                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
   9188                 if (cpr != null) {
   9189                     cpi = cpr.info;
   9190                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   9191                             cpi.name, cpi.flags)
   9192                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   9193                         userId = UserHandle.USER_OWNER;
   9194                         checkCrossUser = false;
   9195                     } else {
   9196                         cpr = null;
   9197                         cpi = null;
   9198                     }
   9199                 }
   9200             }
   9201 
   9202             boolean providerRunning = cpr != null;
   9203             if (providerRunning) {
   9204                 cpi = cpr.info;
   9205                 String msg;
   9206                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9207                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   9208                         != null) {
   9209                     throw new SecurityException(msg);
   9210                 }
   9211                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9212 
   9213                 if (r != null && cpr.canRunHere(r)) {
   9214                     // This provider has been published or is in the process
   9215                     // of being published...  but it is also allowed to run
   9216                     // in the caller's process, so don't make a connection
   9217                     // and just let the caller instantiate its own instance.
   9218                     ContentProviderHolder holder = cpr.newHolder(null);
   9219                     // don't give caller the provider object, it needs
   9220                     // to make its own.
   9221                     holder.provider = null;
   9222                     return holder;
   9223                 }
   9224 
   9225                 final long origId = Binder.clearCallingIdentity();
   9226 
   9227                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   9228 
   9229                 // In this case the provider instance already exists, so we can
   9230                 // return it right away.
   9231                 conn = incProviderCountLocked(r, cpr, token, stable);
   9232                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   9233                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9234                         // If this is a perceptible app accessing the provider,
   9235                         // make sure to count it as being accessed and thus
   9236                         // back up on the LRU list.  This is good because
   9237                         // content providers are often expensive to start.
   9238                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   9239                         updateLruProcessLocked(cpr.proc, false, null);
   9240                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   9241                     }
   9242                 }
   9243 
   9244                 if (cpr.proc != null) {
   9245                     if (false) {
   9246                         if (cpr.name.flattenToShortString().equals(
   9247                                 "com.android.providers.calendar/.CalendarProvider2")) {
   9248                             Slog.v(TAG, "****************** KILLING "
   9249                                 + cpr.name.flattenToShortString());
   9250                             Process.killProcess(cpr.proc.pid);
   9251                         }
   9252                     }
   9253                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   9254                     boolean success = updateOomAdjLocked(cpr.proc);
   9255                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   9256                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   9257                     // NOTE: there is still a race here where a signal could be
   9258                     // pending on the process even though we managed to update its
   9259                     // adj level.  Not sure what to do about this, but at least
   9260                     // the race is now smaller.
   9261                     if (!success) {
   9262                         // Uh oh...  it looks like the provider's process
   9263                         // has been killed on us.  We need to wait for a new
   9264                         // process to be started, and make sure its death
   9265                         // doesn't kill our process.
   9266                         Slog.i(TAG,
   9267                                 "Existing provider " + cpr.name.flattenToShortString()
   9268                                 + " is crashing; detaching " + r);
   9269                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   9270                         checkTime(startTime, "getContentProviderImpl: before appDied");
   9271                         appDiedLocked(cpr.proc);
   9272                         checkTime(startTime, "getContentProviderImpl: after appDied");
   9273                         if (!lastRef) {
   9274                             // This wasn't the last ref our process had on
   9275                             // the provider...  we have now been killed, bail.
   9276                             return null;
   9277                         }
   9278                         providerRunning = false;
   9279                         conn = null;
   9280                     }
   9281                 }
   9282 
   9283                 Binder.restoreCallingIdentity(origId);
   9284             }
   9285 
   9286             boolean singleton;
   9287             if (!providerRunning) {
   9288                 try {
   9289                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   9290                     cpi = AppGlobals.getPackageManager().
   9291                         resolveContentProvider(name,
   9292                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   9293                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   9294                 } catch (RemoteException ex) {
   9295                 }
   9296                 if (cpi == null) {
   9297                     return null;
   9298                 }
   9299                 // If the provider is a singleton AND
   9300                 // (it's a call within the same user || the provider is a
   9301                 // privileged app)
   9302                 // Then allow connecting to the singleton provider
   9303                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   9304                         cpi.name, cpi.flags)
   9305                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   9306                 if (singleton) {
   9307                     userId = UserHandle.USER_OWNER;
   9308                 }
   9309                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   9310                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   9311 
   9312                 String msg;
   9313                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9314                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   9315                         != null) {
   9316                     throw new SecurityException(msg);
   9317                 }
   9318                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9319 
   9320                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   9321                         && !cpi.processName.equals("system")) {
   9322                     // If this content provider does not run in the system
   9323                     // process, and the system is not yet ready to run other
   9324                     // processes, then fail fast instead of hanging.
   9325                     throw new IllegalArgumentException(
   9326                             "Attempt to launch content provider before system ready");
   9327                 }
   9328 
   9329                 // Make sure that the user who owns this provider is running.  If not,
   9330                 // we don't want to allow it to run.
   9331                 if (!isUserRunningLocked(userId, false)) {
   9332                     Slog.w(TAG, "Unable to launch app "
   9333                             + cpi.applicationInfo.packageName + "/"
   9334                             + cpi.applicationInfo.uid + " for provider "
   9335                             + name + ": user " + userId + " is stopped");
   9336                     return null;
   9337                 }
   9338 
   9339                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   9340                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   9341                 cpr = mProviderMap.getProviderByClass(comp, userId);
   9342                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   9343                 final boolean firstClass = cpr == null;
   9344                 if (firstClass) {
   9345                     final long ident = Binder.clearCallingIdentity();
   9346                     try {
   9347                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   9348                         ApplicationInfo ai =
   9349                             AppGlobals.getPackageManager().
   9350                                 getApplicationInfo(
   9351                                         cpi.applicationInfo.packageName,
   9352                                         STOCK_PM_FLAGS, userId);
   9353                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   9354                         if (ai == null) {
   9355                             Slog.w(TAG, "No package info for content provider "
   9356                                     + cpi.name);
   9357                             return null;
   9358                         }
   9359                         ai = getAppInfoForUser(ai, userId);
   9360                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   9361                     } catch (RemoteException ex) {
   9362                         // pm is in same process, this will never happen.
   9363                     } finally {
   9364                         Binder.restoreCallingIdentity(ident);
   9365                     }
   9366                 }
   9367 
   9368                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   9369 
   9370                 if (r != null && cpr.canRunHere(r)) {
   9371                     // If this is a multiprocess provider, then just return its
   9372                     // info and allow the caller to instantiate it.  Only do
   9373                     // this if the provider is the same user as the caller's
   9374                     // process, or can run as root (so can be in any process).
   9375                     return cpr.newHolder(null);
   9376                 }
   9377 
   9378                 if (DEBUG_PROVIDER) {
   9379                     RuntimeException e = new RuntimeException("here");
   9380                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
   9381                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   9382                 }
   9383 
   9384                 // This is single process, and our app is now connecting to it.
   9385                 // See if we are already in the process of launching this
   9386                 // provider.
   9387                 final int N = mLaunchingProviders.size();
   9388                 int i;
   9389                 for (i=0; i<N; i++) {
   9390                     if (mLaunchingProviders.get(i) == cpr) {
   9391                         break;
   9392                     }
   9393                 }
   9394 
   9395                 // If the provider is not already being launched, then get it
   9396                 // started.
   9397                 if (i >= N) {
   9398                     final long origId = Binder.clearCallingIdentity();
   9399 
   9400                     try {
   9401                         // Content provider is now in use, its package can't be stopped.
   9402                         try {
   9403                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   9404                             AppGlobals.getPackageManager().setPackageStoppedState(
   9405                                     cpr.appInfo.packageName, false, userId);
   9406                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   9407                         } catch (RemoteException e) {
   9408                         } catch (IllegalArgumentException e) {
   9409                             Slog.w(TAG, "Failed trying to unstop package "
   9410                                     + cpr.appInfo.packageName + ": " + e);
   9411                         }
   9412 
   9413                         // Use existing process if already started
   9414                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   9415                         ProcessRecord proc = getProcessRecordLocked(
   9416                                 cpi.processName, cpr.appInfo.uid, false);
   9417                         if (proc != null && proc.thread != null) {
   9418                             if (DEBUG_PROVIDER) {
   9419                                 Slog.d(TAG, "Installing in existing process " + proc);
   9420                             }
   9421                             checkTime(startTime, "getContentProviderImpl: scheduling install");
   9422                             proc.pubProviders.put(cpi.name, cpr);
   9423                             try {
   9424                                 proc.thread.scheduleInstallProvider(cpi);
   9425                             } catch (RemoteException e) {
   9426                             }
   9427                         } else {
   9428                             checkTime(startTime, "getContentProviderImpl: before start process");
   9429                             proc = startProcessLocked(cpi.processName,
   9430                                     cpr.appInfo, false, 0, "content provider",
   9431                                     new ComponentName(cpi.applicationInfo.packageName,
   9432                                             cpi.name), false, false, false);
   9433                             checkTime(startTime, "getContentProviderImpl: after start process");
   9434                             if (proc == null) {
   9435                                 Slog.w(TAG, "Unable to launch app "
   9436                                         + cpi.applicationInfo.packageName + "/"
   9437                                         + cpi.applicationInfo.uid + " for provider "
   9438                                         + name + ": process is bad");
   9439                                 return null;
   9440                             }
   9441                         }
   9442                         cpr.launchingApp = proc;
   9443                         mLaunchingProviders.add(cpr);
   9444                     } finally {
   9445                         Binder.restoreCallingIdentity(origId);
   9446                     }
   9447                 }
   9448 
   9449                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   9450 
   9451                 // Make sure the provider is published (the same provider class
   9452                 // may be published under multiple names).
   9453                 if (firstClass) {
   9454                     mProviderMap.putProviderByClass(comp, cpr);
   9455                 }
   9456 
   9457                 mProviderMap.putProviderByName(name, cpr);
   9458                 conn = incProviderCountLocked(r, cpr, token, stable);
   9459                 if (conn != null) {
   9460                     conn.waiting = true;
   9461                 }
   9462             }
   9463             checkTime(startTime, "getContentProviderImpl: done!");
   9464         }
   9465 
   9466         // Wait for the provider to be published...
   9467         synchronized (cpr) {
   9468             while (cpr.provider == null) {
   9469                 if (cpr.launchingApp == null) {
   9470                     Slog.w(TAG, "Unable to launch app "
   9471                             + cpi.applicationInfo.packageName + "/"
   9472                             + cpi.applicationInfo.uid + " for provider "
   9473                             + name + ": launching app became null");
   9474                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   9475                             UserHandle.getUserId(cpi.applicationInfo.uid),
   9476                             cpi.applicationInfo.packageName,
   9477                             cpi.applicationInfo.uid, name);
   9478                     return null;
   9479                 }
   9480                 try {
   9481                     if (DEBUG_MU) {
   9482                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   9483                                 + cpr.launchingApp);
   9484                     }
   9485                     if (conn != null) {
   9486                         conn.waiting = true;
   9487                     }
   9488                     cpr.wait();
   9489                 } catch (InterruptedException ex) {
   9490                 } finally {
   9491                     if (conn != null) {
   9492                         conn.waiting = false;
   9493                     }
   9494                 }
   9495             }
   9496         }
   9497         return cpr != null ? cpr.newHolder(conn) : null;
   9498     }
   9499 
   9500     @Override
   9501     public final ContentProviderHolder getContentProvider(
   9502             IApplicationThread caller, String name, int userId, boolean stable) {
   9503         enforceNotIsolatedCaller("getContentProvider");
   9504         if (caller == null) {
   9505             String msg = "null IApplicationThread when getting content provider "
   9506                     + name;
   9507             Slog.w(TAG, msg);
   9508             throw new SecurityException(msg);
   9509         }
   9510         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   9511         // with cross-user grant.
   9512         return getContentProviderImpl(caller, name, null, stable, userId);
   9513     }
   9514 
   9515     public ContentProviderHolder getContentProviderExternal(
   9516             String name, int userId, IBinder token) {
   9517         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9518             "Do not have permission in call getContentProviderExternal()");
   9519         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   9520                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
   9521         return getContentProviderExternalUnchecked(name, token, userId);
   9522     }
   9523 
   9524     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   9525             IBinder token, int userId) {
   9526         return getContentProviderImpl(null, name, token, true, userId);
   9527     }
   9528 
   9529     /**
   9530      * Drop a content provider from a ProcessRecord's bookkeeping
   9531      */
   9532     public void removeContentProvider(IBinder connection, boolean stable) {
   9533         enforceNotIsolatedCaller("removeContentProvider");
   9534         long ident = Binder.clearCallingIdentity();
   9535         try {
   9536             synchronized (this) {
   9537                 ContentProviderConnection conn;
   9538                 try {
   9539                     conn = (ContentProviderConnection)connection;
   9540                 } catch (ClassCastException e) {
   9541                     String msg ="removeContentProvider: " + connection
   9542                             + " not a ContentProviderConnection";
   9543                     Slog.w(TAG, msg);
   9544                     throw new IllegalArgumentException(msg);
   9545                 }
   9546                 if (conn == null) {
   9547                     throw new NullPointerException("connection is null");
   9548                 }
   9549                 if (decProviderCountLocked(conn, null, null, stable)) {
   9550                     updateOomAdjLocked();
   9551                 }
   9552             }
   9553         } finally {
   9554             Binder.restoreCallingIdentity(ident);
   9555         }
   9556     }
   9557 
   9558     public void removeContentProviderExternal(String name, IBinder token) {
   9559         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9560             "Do not have permission in call removeContentProviderExternal()");
   9561         int userId = UserHandle.getCallingUserId();
   9562         long ident = Binder.clearCallingIdentity();
   9563         try {
   9564             removeContentProviderExternalUnchecked(name, token, userId);
   9565         } finally {
   9566             Binder.restoreCallingIdentity(ident);
   9567         }
   9568     }
   9569 
   9570     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   9571         synchronized (this) {
   9572             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   9573             if(cpr == null) {
   9574                 //remove from mProvidersByClass
   9575                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   9576                 return;
   9577             }
   9578 
   9579             //update content provider record entry info
   9580             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   9581             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   9582             if (localCpr.hasExternalProcessHandles()) {
   9583                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   9584                     updateOomAdjLocked();
   9585                 } else {
   9586                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   9587                             + " with no external reference for token: "
   9588                             + token + ".");
   9589                 }
   9590             } else {
   9591                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   9592                         + " with no external references.");
   9593             }
   9594         }
   9595     }
   9596 
   9597     public final void publishContentProviders(IApplicationThread caller,
   9598             List<ContentProviderHolder> providers) {
   9599         if (providers == null) {
   9600             return;
   9601         }
   9602 
   9603         enforceNotIsolatedCaller("publishContentProviders");
   9604         synchronized (this) {
   9605             final ProcessRecord r = getRecordForAppLocked(caller);
   9606             if (DEBUG_MU)
   9607                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   9608             if (r == null) {
   9609                 throw new SecurityException(
   9610                         "Unable to find app for caller " + caller
   9611                       + " (pid=" + Binder.getCallingPid()
   9612                       + ") when publishing content providers");
   9613             }
   9614 
   9615             final long origId = Binder.clearCallingIdentity();
   9616 
   9617             final int N = providers.size();
   9618             for (int i=0; i<N; i++) {
   9619                 ContentProviderHolder src = providers.get(i);
   9620                 if (src == null || src.info == null || src.provider == null) {
   9621                     continue;
   9622                 }
   9623                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   9624                 if (DEBUG_MU)
   9625                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   9626                 if (dst != null) {
   9627                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   9628                     mProviderMap.putProviderByClass(comp, dst);
   9629                     String names[] = dst.info.authority.split(";");
   9630                     for (int j = 0; j < names.length; j++) {
   9631                         mProviderMap.putProviderByName(names[j], dst);
   9632                     }
   9633 
   9634                     int NL = mLaunchingProviders.size();
   9635                     int j;
   9636                     for (j=0; j<NL; j++) {
   9637                         if (mLaunchingProviders.get(j) == dst) {
   9638                             mLaunchingProviders.remove(j);
   9639                             j--;
   9640                             NL--;
   9641                         }
   9642                     }
   9643                     synchronized (dst) {
   9644                         dst.provider = src.provider;
   9645                         dst.proc = r;
   9646                         dst.notifyAll();
   9647                     }
   9648                     updateOomAdjLocked(r);
   9649                 }
   9650             }
   9651 
   9652             Binder.restoreCallingIdentity(origId);
   9653         }
   9654     }
   9655 
   9656     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   9657         ContentProviderConnection conn;
   9658         try {
   9659             conn = (ContentProviderConnection)connection;
   9660         } catch (ClassCastException e) {
   9661             String msg ="refContentProvider: " + connection
   9662                     + " not a ContentProviderConnection";
   9663             Slog.w(TAG, msg);
   9664             throw new IllegalArgumentException(msg);
   9665         }
   9666         if (conn == null) {
   9667             throw new NullPointerException("connection is null");
   9668         }
   9669 
   9670         synchronized (this) {
   9671             if (stable > 0) {
   9672                 conn.numStableIncs += stable;
   9673             }
   9674             stable = conn.stableCount + stable;
   9675             if (stable < 0) {
   9676                 throw new IllegalStateException("stableCount < 0: " + stable);
   9677             }
   9678 
   9679             if (unstable > 0) {
   9680                 conn.numUnstableIncs += unstable;
   9681             }
   9682             unstable = conn.unstableCount + unstable;
   9683             if (unstable < 0) {
   9684                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   9685             }
   9686 
   9687             if ((stable+unstable) <= 0) {
   9688                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   9689                         + stable + " unstable=" + unstable);
   9690             }
   9691             conn.stableCount = stable;
   9692             conn.unstableCount = unstable;
   9693             return !conn.dead;
   9694         }
   9695     }
   9696 
   9697     public void unstableProviderDied(IBinder connection) {
   9698         ContentProviderConnection conn;
   9699         try {
   9700             conn = (ContentProviderConnection)connection;
   9701         } catch (ClassCastException e) {
   9702             String msg ="refContentProvider: " + connection
   9703                     + " not a ContentProviderConnection";
   9704             Slog.w(TAG, msg);
   9705             throw new IllegalArgumentException(msg);
   9706         }
   9707         if (conn == null) {
   9708             throw new NullPointerException("connection is null");
   9709         }
   9710 
   9711         // Safely retrieve the content provider associated with the connection.
   9712         IContentProvider provider;
   9713         synchronized (this) {
   9714             provider = conn.provider.provider;
   9715         }
   9716 
   9717         if (provider == null) {
   9718             // Um, yeah, we're way ahead of you.
   9719             return;
   9720         }
   9721 
   9722         // Make sure the caller is being honest with us.
   9723         if (provider.asBinder().pingBinder()) {
   9724             // Er, no, still looks good to us.
   9725             synchronized (this) {
   9726                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   9727                         + " says " + conn + " died, but we don't agree");
   9728                 return;
   9729             }
   9730         }
   9731 
   9732         // Well look at that!  It's dead!
   9733         synchronized (this) {
   9734             if (conn.provider.provider != provider) {
   9735                 // But something changed...  good enough.
   9736                 return;
   9737             }
   9738 
   9739             ProcessRecord proc = conn.provider.proc;
   9740             if (proc == null || proc.thread == null) {
   9741                 // Seems like the process is already cleaned up.
   9742                 return;
   9743             }
   9744 
   9745             // As far as we're concerned, this is just like receiving a
   9746             // death notification...  just a bit prematurely.
   9747             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   9748                     + ") early provider death");
   9749             final long ident = Binder.clearCallingIdentity();
   9750             try {
   9751                 appDiedLocked(proc);
   9752             } finally {
   9753                 Binder.restoreCallingIdentity(ident);
   9754             }
   9755         }
   9756     }
   9757 
   9758     @Override
   9759     public void appNotRespondingViaProvider(IBinder connection) {
   9760         enforceCallingPermission(
   9761                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   9762 
   9763         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   9764         if (conn == null) {
   9765             Slog.w(TAG, "ContentProviderConnection is null");
   9766             return;
   9767         }
   9768 
   9769         final ProcessRecord host = conn.provider.proc;
   9770         if (host == null) {
   9771             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   9772             return;
   9773         }
   9774 
   9775         final long token = Binder.clearCallingIdentity();
   9776         try {
   9777             appNotResponding(host, null, null, false, "ContentProvider not responding");
   9778         } finally {
   9779             Binder.restoreCallingIdentity(token);
   9780         }
   9781     }
   9782 
   9783     public final void installSystemProviders() {
   9784         List<ProviderInfo> providers;
   9785         synchronized (this) {
   9786             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   9787             providers = generateApplicationProvidersLocked(app);
   9788             if (providers != null) {
   9789                 for (int i=providers.size()-1; i>=0; i--) {
   9790                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   9791                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   9792                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   9793                                 + ": not system .apk");
   9794                         providers.remove(i);
   9795                     }
   9796                 }
   9797             }
   9798         }
   9799         if (providers != null) {
   9800             mSystemThread.installSystemProviders(providers);
   9801         }
   9802 
   9803         mCoreSettingsObserver = new CoreSettingsObserver(this);
   9804 
   9805         //mUsageStatsService.monitorPackages();
   9806     }
   9807 
   9808     /**
   9809      * Allows apps to retrieve the MIME type of a URI.
   9810      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   9811      * users, then it does not need permission to access the ContentProvider.
   9812      * Either, it needs cross-user uri grants.
   9813      *
   9814      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   9815      *
   9816      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   9817      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   9818      */
   9819     public String getProviderMimeType(Uri uri, int userId) {
   9820         enforceNotIsolatedCaller("getProviderMimeType");
   9821         final String name = uri.getAuthority();
   9822         int callingUid = Binder.getCallingUid();
   9823         int callingPid = Binder.getCallingPid();
   9824         long ident = 0;
   9825         boolean clearedIdentity = false;
   9826         userId = unsafeConvertIncomingUser(userId);
   9827         if (canClearIdentity(callingPid, callingUid, userId)) {
   9828             clearedIdentity = true;
   9829             ident = Binder.clearCallingIdentity();
   9830         }
   9831         ContentProviderHolder holder = null;
   9832         try {
   9833             holder = getContentProviderExternalUnchecked(name, null, userId);
   9834             if (holder != null) {
   9835                 return holder.provider.getType(uri);
   9836             }
   9837         } catch (RemoteException e) {
   9838             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   9839             return null;
   9840         } finally {
   9841             // We need to clear the identity to call removeContentProviderExternalUnchecked
   9842             if (!clearedIdentity) {
   9843                 ident = Binder.clearCallingIdentity();
   9844             }
   9845             try {
   9846                 if (holder != null) {
   9847                     removeContentProviderExternalUnchecked(name, null, userId);
   9848                 }
   9849             } finally {
   9850                 Binder.restoreCallingIdentity(ident);
   9851             }
   9852         }
   9853 
   9854         return null;
   9855     }
   9856 
   9857     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   9858         if (UserHandle.getUserId(callingUid) == userId) {
   9859             return true;
   9860         }
   9861         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   9862                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   9863                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   9864                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   9865                 return true;
   9866         }
   9867         return false;
   9868     }
   9869 
   9870     // =========================================================
   9871     // GLOBAL MANAGEMENT
   9872     // =========================================================
   9873 
   9874     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   9875             boolean isolated, int isolatedUid) {
   9876         String proc = customProcess != null ? customProcess : info.processName;
   9877         BatteryStatsImpl.Uid.Proc ps = null;
   9878         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9879         int uid = info.uid;
   9880         if (isolated) {
   9881             if (isolatedUid == 0) {
   9882                 int userId = UserHandle.getUserId(uid);
   9883                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   9884                 while (true) {
   9885                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   9886                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   9887                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   9888                     }
   9889                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   9890                     mNextIsolatedProcessUid++;
   9891                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   9892                         // No process for this uid, use it.
   9893                         break;
   9894                     }
   9895                     stepsLeft--;
   9896                     if (stepsLeft <= 0) {
   9897                         return null;
   9898                     }
   9899                 }
   9900             } else {
   9901                 // Special case for startIsolatedProcess (internal only), where
   9902                 // the uid of the isolated process is specified by the caller.
   9903                 uid = isolatedUid;
   9904             }
   9905         }
   9906         return new ProcessRecord(stats, info, proc, uid);
   9907     }
   9908 
   9909     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   9910             String abiOverride) {
   9911         ProcessRecord app;
   9912         if (!isolated) {
   9913             app = getProcessRecordLocked(info.processName, info.uid, true);
   9914         } else {
   9915             app = null;
   9916         }
   9917 
   9918         if (app == null) {
   9919             app = newProcessRecordLocked(info, null, isolated, 0);
   9920             mProcessNames.put(info.processName, app.uid, app);
   9921             if (isolated) {
   9922                 mIsolatedProcesses.put(app.uid, app);
   9923             }
   9924             updateLruProcessLocked(app, false, null);
   9925             updateOomAdjLocked();
   9926         }
   9927 
   9928         // This package really, really can not be stopped.
   9929         try {
   9930             AppGlobals.getPackageManager().setPackageStoppedState(
   9931                     info.packageName, false, UserHandle.getUserId(app.uid));
   9932         } catch (RemoteException e) {
   9933         } catch (IllegalArgumentException e) {
   9934             Slog.w(TAG, "Failed trying to unstop package "
   9935                     + info.packageName + ": " + e);
   9936         }
   9937 
   9938         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   9939                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   9940             app.persistent = true;
   9941             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   9942         }
   9943         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   9944             mPersistentStartingProcesses.add(app);
   9945             startProcessLocked(app, "added application", app.processName, abiOverride,
   9946                     null /* entryPoint */, null /* entryPointArgs */);
   9947         }
   9948 
   9949         return app;
   9950     }
   9951 
   9952     public void unhandledBack() {
   9953         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   9954                 "unhandledBack()");
   9955 
   9956         synchronized(this) {
   9957             final long origId = Binder.clearCallingIdentity();
   9958             try {
   9959                 getFocusedStack().unhandledBackLocked();
   9960             } finally {
   9961                 Binder.restoreCallingIdentity(origId);
   9962             }
   9963         }
   9964     }
   9965 
   9966     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   9967         enforceNotIsolatedCaller("openContentUri");
   9968         final int userId = UserHandle.getCallingUserId();
   9969         String name = uri.getAuthority();
   9970         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   9971         ParcelFileDescriptor pfd = null;
   9972         if (cph != null) {
   9973             // We record the binder invoker's uid in thread-local storage before
   9974             // going to the content provider to open the file.  Later, in the code
   9975             // that handles all permissions checks, we look for this uid and use
   9976             // that rather than the Activity Manager's own uid.  The effect is that
   9977             // we do the check against the caller's permissions even though it looks
   9978             // to the content provider like the Activity Manager itself is making
   9979             // the request.
   9980             Binder token = new Binder();
   9981             sCallerIdentity.set(new Identity(
   9982                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   9983             try {
   9984                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   9985             } catch (FileNotFoundException e) {
   9986                 // do nothing; pfd will be returned null
   9987             } finally {
   9988                 // Ensure that whatever happens, we clean up the identity state
   9989                 sCallerIdentity.remove();
   9990             }
   9991 
   9992             // We've got the fd now, so we're done with the provider.
   9993             removeContentProviderExternalUnchecked(name, null, userId);
   9994         } else {
   9995             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   9996         }
   9997         return pfd;
   9998     }
   9999 
   10000     // Actually is sleeping or shutting down or whatever else in the future
   10001     // is an inactive state.
   10002     public boolean isSleepingOrShuttingDown() {
   10003         return isSleeping() || mShuttingDown;
   10004     }
   10005 
   10006     public boolean isSleeping() {
   10007         return mSleeping;
   10008     }
   10009 
   10010     void onWakefulnessChanged(int wakefulness) {
   10011         synchronized(this) {
   10012             mWakefulness = wakefulness;
   10013             updateSleepIfNeededLocked();
   10014         }
   10015     }
   10016 
   10017     void finishRunningVoiceLocked() {
   10018         if (mRunningVoice) {
   10019             mRunningVoice = false;
   10020             updateSleepIfNeededLocked();
   10021         }
   10022     }
   10023 
   10024     void updateSleepIfNeededLocked() {
   10025         if (mSleeping && !shouldSleepLocked()) {
   10026             mSleeping = false;
   10027             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   10028         } else if (!mSleeping && shouldSleepLocked()) {
   10029             mSleeping = true;
   10030             mStackSupervisor.goingToSleepLocked();
   10031 
   10032             // Initialize the wake times of all processes.
   10033             checkExcessivePowerUsageLocked(false);
   10034             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10035             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10036             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   10037         }
   10038     }
   10039 
   10040     private boolean shouldSleepLocked() {
   10041         // Resume applications while running a voice interactor.
   10042         if (mRunningVoice) {
   10043             return false;
   10044         }
   10045 
   10046         switch (mWakefulness) {
   10047             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   10048             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   10049                 // If we're interactive but applications are already paused then defer
   10050                 // resuming them until the lock screen is hidden.
   10051                 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
   10052             case PowerManagerInternal.WAKEFULNESS_DOZING:
   10053                 // If we're dozing then pause applications whenever the lock screen is shown.
   10054                 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
   10055             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   10056             default:
   10057                 // If we're asleep then pause applications unconditionally.
   10058                 return true;
   10059         }
   10060     }
   10061 
   10062     /** Pokes the task persister. */
   10063     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   10064         if (task != null && task.stack != null && task.stack.isHomeStack()) {
   10065             // Never persist the home stack.
   10066             return;
   10067         }
   10068         mTaskPersister.wakeup(task, flush);
   10069     }
   10070 
   10071     /** Notifies all listeners when the task stack has changed. */
   10072     void notifyTaskStackChangedLocked() {
   10073         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   10074         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   10075         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
   10076     }
   10077 
   10078     @Override
   10079     public boolean shutdown(int timeout) {
   10080         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   10081                 != PackageManager.PERMISSION_GRANTED) {
   10082             throw new SecurityException("Requires permission "
   10083                     + android.Manifest.permission.SHUTDOWN);
   10084         }
   10085 
   10086         boolean timedout = false;
   10087 
   10088         synchronized(this) {
   10089             mShuttingDown = true;
   10090             updateEventDispatchingLocked();
   10091             timedout = mStackSupervisor.shutdownLocked(timeout);
   10092         }
   10093 
   10094         mAppOpsService.shutdown();
   10095         if (mUsageStatsService != null) {
   10096             mUsageStatsService.prepareShutdown();
   10097         }
   10098         mBatteryStatsService.shutdown();
   10099         synchronized (this) {
   10100             mProcessStats.shutdownLocked();
   10101             notifyTaskPersisterLocked(null, true);
   10102         }
   10103 
   10104         return timedout;
   10105     }
   10106 
   10107     public final void activitySlept(IBinder token) {
   10108         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
   10109 
   10110         final long origId = Binder.clearCallingIdentity();
   10111 
   10112         synchronized (this) {
   10113             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10114             if (r != null) {
   10115                 mStackSupervisor.activitySleptLocked(r);
   10116             }
   10117         }
   10118 
   10119         Binder.restoreCallingIdentity(origId);
   10120     }
   10121 
   10122     private String lockScreenShownToString() {
   10123         switch (mLockScreenShown) {
   10124             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
   10125             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
   10126             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
   10127             default: return "Unknown=" + mLockScreenShown;
   10128         }
   10129     }
   10130 
   10131     void logLockScreen(String msg) {
   10132         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
   10133                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
   10134                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
   10135                 + " mSleeping=" + mSleeping);
   10136     }
   10137 
   10138     void startRunningVoiceLocked() {
   10139         if (!mRunningVoice) {
   10140             mRunningVoice = true;
   10141             updateSleepIfNeededLocked();
   10142         }
   10143     }
   10144 
   10145     private void updateEventDispatchingLocked() {
   10146         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   10147     }
   10148 
   10149     public void setLockScreenShown(boolean shown) {
   10150         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   10151                 != PackageManager.PERMISSION_GRANTED) {
   10152             throw new SecurityException("Requires permission "
   10153                     + android.Manifest.permission.DEVICE_POWER);
   10154         }
   10155 
   10156         synchronized(this) {
   10157             long ident = Binder.clearCallingIdentity();
   10158             try {
   10159                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
   10160                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
   10161                 updateSleepIfNeededLocked();
   10162             } finally {
   10163                 Binder.restoreCallingIdentity(ident);
   10164             }
   10165         }
   10166     }
   10167 
   10168     @Override
   10169     public void stopAppSwitches() {
   10170         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10171                 != PackageManager.PERMISSION_GRANTED) {
   10172             throw new SecurityException("Requires permission "
   10173                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10174         }
   10175 
   10176         synchronized(this) {
   10177             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   10178                     + APP_SWITCH_DELAY_TIME;
   10179             mDidAppSwitch = false;
   10180             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10181             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10182             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   10183         }
   10184     }
   10185 
   10186     public void resumeAppSwitches() {
   10187         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10188                 != PackageManager.PERMISSION_GRANTED) {
   10189             throw new SecurityException("Requires permission "
   10190                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10191         }
   10192 
   10193         synchronized(this) {
   10194             // Note that we don't execute any pending app switches... we will
   10195             // let those wait until either the timeout, or the next start
   10196             // activity request.
   10197             mAppSwitchesAllowedTime = 0;
   10198         }
   10199     }
   10200 
   10201     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   10202             int callingPid, int callingUid, String name) {
   10203         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   10204             return true;
   10205         }
   10206 
   10207         int perm = checkComponentPermission(
   10208                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   10209                 sourceUid, -1, true);
   10210         if (perm == PackageManager.PERMISSION_GRANTED) {
   10211             return true;
   10212         }
   10213 
   10214         // If the actual IPC caller is different from the logical source, then
   10215         // also see if they are allowed to control app switches.
   10216         if (callingUid != -1 && callingUid != sourceUid) {
   10217             perm = checkComponentPermission(
   10218                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   10219                     callingUid, -1, true);
   10220             if (perm == PackageManager.PERMISSION_GRANTED) {
   10221                 return true;
   10222             }
   10223         }
   10224 
   10225         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   10226         return false;
   10227     }
   10228 
   10229     public void setDebugApp(String packageName, boolean waitForDebugger,
   10230             boolean persistent) {
   10231         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   10232                 "setDebugApp()");
   10233 
   10234         long ident = Binder.clearCallingIdentity();
   10235         try {
   10236             // Note that this is not really thread safe if there are multiple
   10237             // callers into it at the same time, but that's not a situation we
   10238             // care about.
   10239             if (persistent) {
   10240                 final ContentResolver resolver = mContext.getContentResolver();
   10241                 Settings.Global.putString(
   10242                     resolver, Settings.Global.DEBUG_APP,
   10243                     packageName);
   10244                 Settings.Global.putInt(
   10245                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   10246                     waitForDebugger ? 1 : 0);
   10247             }
   10248 
   10249             synchronized (this) {
   10250                 if (!persistent) {
   10251                     mOrigDebugApp = mDebugApp;
   10252                     mOrigWaitForDebugger = mWaitForDebugger;
   10253                 }
   10254                 mDebugApp = packageName;
   10255                 mWaitForDebugger = waitForDebugger;
   10256                 mDebugTransient = !persistent;
   10257                 if (packageName != null) {
   10258                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   10259                             false, UserHandle.USER_ALL, "set debug app");
   10260                 }
   10261             }
   10262         } finally {
   10263             Binder.restoreCallingIdentity(ident);
   10264         }
   10265     }
   10266 
   10267     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   10268         synchronized (this) {
   10269             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10270             if (!isDebuggable) {
   10271                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10272                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10273                 }
   10274             }
   10275 
   10276             mOpenGlTraceApp = processName;
   10277         }
   10278     }
   10279 
   10280     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   10281         synchronized (this) {
   10282             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10283             if (!isDebuggable) {
   10284                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10285                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10286                 }
   10287             }
   10288             mProfileApp = processName;
   10289             mProfileFile = profilerInfo.profileFile;
   10290             if (mProfileFd != null) {
   10291                 try {
   10292                     mProfileFd.close();
   10293                 } catch (IOException e) {
   10294                 }
   10295                 mProfileFd = null;
   10296             }
   10297             mProfileFd = profilerInfo.profileFd;
   10298             mSamplingInterval = profilerInfo.samplingInterval;
   10299             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   10300             mProfileType = 0;
   10301         }
   10302     }
   10303 
   10304     @Override
   10305     public void setAlwaysFinish(boolean enabled) {
   10306         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   10307                 "setAlwaysFinish()");
   10308 
   10309         Settings.Global.putInt(
   10310                 mContext.getContentResolver(),
   10311                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   10312 
   10313         synchronized (this) {
   10314             mAlwaysFinishActivities = enabled;
   10315         }
   10316     }
   10317 
   10318     @Override
   10319     public void setActivityController(IActivityController controller) {
   10320         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10321                 "setActivityController()");
   10322         synchronized (this) {
   10323             mController = controller;
   10324             Watchdog.getInstance().setActivityController(controller);
   10325         }
   10326     }
   10327 
   10328     @Override
   10329     public void setUserIsMonkey(boolean userIsMonkey) {
   10330         synchronized (this) {
   10331             synchronized (mPidsSelfLocked) {
   10332                 final int callingPid = Binder.getCallingPid();
   10333                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   10334                 if (precessRecord == null) {
   10335                     throw new SecurityException("Unknown process: " + callingPid);
   10336                 }
   10337                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   10338                     throw new SecurityException("Only an instrumentation process "
   10339                             + "with a UiAutomation can call setUserIsMonkey");
   10340                 }
   10341             }
   10342             mUserIsMonkey = userIsMonkey;
   10343         }
   10344     }
   10345 
   10346     @Override
   10347     public boolean isUserAMonkey() {
   10348         synchronized (this) {
   10349             // If there is a controller also implies the user is a monkey.
   10350             return (mUserIsMonkey || mController != null);
   10351         }
   10352     }
   10353 
   10354     public void requestBugReport() {
   10355         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   10356         SystemProperties.set("ctl.start", "bugreport");
   10357     }
   10358 
   10359     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   10360         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   10361     }
   10362 
   10363     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   10364         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   10365             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   10366         }
   10367         return KEY_DISPATCHING_TIMEOUT;
   10368     }
   10369 
   10370     @Override
   10371     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   10372         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10373                 != PackageManager.PERMISSION_GRANTED) {
   10374             throw new SecurityException("Requires permission "
   10375                     + android.Manifest.permission.FILTER_EVENTS);
   10376         }
   10377         ProcessRecord proc;
   10378         long timeout;
   10379         synchronized (this) {
   10380             synchronized (mPidsSelfLocked) {
   10381                 proc = mPidsSelfLocked.get(pid);
   10382             }
   10383             timeout = getInputDispatchingTimeoutLocked(proc);
   10384         }
   10385 
   10386         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   10387             return -1;
   10388         }
   10389 
   10390         return timeout;
   10391     }
   10392 
   10393     /**
   10394      * Handle input dispatching timeouts.
   10395      * Returns whether input dispatching should be aborted or not.
   10396      */
   10397     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   10398             final ActivityRecord activity, final ActivityRecord parent,
   10399             final boolean aboveSystem, String reason) {
   10400         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10401                 != PackageManager.PERMISSION_GRANTED) {
   10402             throw new SecurityException("Requires permission "
   10403                     + android.Manifest.permission.FILTER_EVENTS);
   10404         }
   10405 
   10406         final String annotation;
   10407         if (reason == null) {
   10408             annotation = "Input dispatching timed out";
   10409         } else {
   10410             annotation = "Input dispatching timed out (" + reason + ")";
   10411         }
   10412 
   10413         if (proc != null) {
   10414             synchronized (this) {
   10415                 if (proc.debugging) {
   10416                     return false;
   10417                 }
   10418 
   10419                 if (mDidDexOpt) {
   10420                     // Give more time since we were dexopting.
   10421                     mDidDexOpt = false;
   10422                     return false;
   10423                 }
   10424 
   10425                 if (proc.instrumentationClass != null) {
   10426                     Bundle info = new Bundle();
   10427                     info.putString("shortMsg", "keyDispatchingTimedOut");
   10428                     info.putString("longMsg", annotation);
   10429                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   10430                     return true;
   10431                 }
   10432             }
   10433             mHandler.post(new Runnable() {
   10434                 @Override
   10435                 public void run() {
   10436                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
   10437                 }
   10438             });
   10439         }
   10440 
   10441         return true;
   10442     }
   10443 
   10444     public Bundle getAssistContextExtras(int requestType) {
   10445         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
   10446                 UserHandle.getCallingUserId());
   10447         if (pae == null) {
   10448             return null;
   10449         }
   10450         synchronized (pae) {
   10451             while (!pae.haveResult) {
   10452                 try {
   10453                     pae.wait();
   10454                 } catch (InterruptedException e) {
   10455                 }
   10456             }
   10457             if (pae.result != null) {
   10458                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   10459             }
   10460         }
   10461         synchronized (this) {
   10462             mPendingAssistExtras.remove(pae);
   10463             mHandler.removeCallbacks(pae);
   10464         }
   10465         return pae.extras;
   10466     }
   10467 
   10468     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   10469             int userHandle) {
   10470         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   10471                 "getAssistContextExtras()");
   10472         PendingAssistExtras pae;
   10473         Bundle extras = new Bundle();
   10474         synchronized (this) {
   10475             ActivityRecord activity = getFocusedStack().mResumedActivity;
   10476             if (activity == null) {
   10477                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
   10478                 return null;
   10479             }
   10480             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   10481             if (activity.app == null || activity.app.thread == null) {
   10482                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   10483                 return null;
   10484             }
   10485             if (activity.app.pid == Binder.getCallingPid()) {
   10486                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
   10487                 return null;
   10488             }
   10489             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
   10490             try {
   10491                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   10492                         requestType);
   10493                 mPendingAssistExtras.add(pae);
   10494                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
   10495             } catch (RemoteException e) {
   10496                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   10497                 return null;
   10498             }
   10499             return pae;
   10500         }
   10501     }
   10502 
   10503     public void reportAssistContextExtras(IBinder token, Bundle extras) {
   10504         PendingAssistExtras pae = (PendingAssistExtras)token;
   10505         synchronized (pae) {
   10506             pae.result = extras;
   10507             pae.haveResult = true;
   10508             pae.notifyAll();
   10509             if (pae.intent == null) {
   10510                 // Caller is just waiting for the result.
   10511                 return;
   10512             }
   10513         }
   10514 
   10515         // We are now ready to launch the assist activity.
   10516         synchronized (this) {
   10517             boolean exists = mPendingAssistExtras.remove(pae);
   10518             mHandler.removeCallbacks(pae);
   10519             if (!exists) {
   10520                 // Timed out.
   10521                 return;
   10522             }
   10523         }
   10524         pae.intent.replaceExtras(extras);
   10525         if (pae.hint != null) {
   10526             pae.intent.putExtra(pae.hint, true);
   10527         }
   10528         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10529                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
   10530                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   10531         closeSystemDialogs("assist");
   10532         try {
   10533             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   10534         } catch (ActivityNotFoundException e) {
   10535             Slog.w(TAG, "No activity to handle assist action.", e);
   10536         }
   10537     }
   10538 
   10539     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
   10540         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
   10541     }
   10542 
   10543     public void registerProcessObserver(IProcessObserver observer) {
   10544         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10545                 "registerProcessObserver()");
   10546         synchronized (this) {
   10547             mProcessObservers.register(observer);
   10548         }
   10549     }
   10550 
   10551     @Override
   10552     public void unregisterProcessObserver(IProcessObserver observer) {
   10553         synchronized (this) {
   10554             mProcessObservers.unregister(observer);
   10555         }
   10556     }
   10557 
   10558     @Override
   10559     public boolean convertFromTranslucent(IBinder token) {
   10560         final long origId = Binder.clearCallingIdentity();
   10561         try {
   10562             synchronized (this) {
   10563                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10564                 if (r == null) {
   10565                     return false;
   10566                 }
   10567                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   10568                 if (translucentChanged) {
   10569                     r.task.stack.releaseBackgroundResources();
   10570                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10571                 }
   10572                 mWindowManager.setAppFullscreen(token, true);
   10573                 return translucentChanged;
   10574             }
   10575         } finally {
   10576             Binder.restoreCallingIdentity(origId);
   10577         }
   10578     }
   10579 
   10580     @Override
   10581     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   10582         final long origId = Binder.clearCallingIdentity();
   10583         try {
   10584             synchronized (this) {
   10585                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10586                 if (r == null) {
   10587                     return false;
   10588                 }
   10589                 int index = r.task.mActivities.lastIndexOf(r);
   10590                 if (index > 0) {
   10591                     ActivityRecord under = r.task.mActivities.get(index - 1);
   10592                     under.returningOptions = options;
   10593                 }
   10594                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   10595                 if (translucentChanged) {
   10596                     r.task.stack.convertToTranslucent(r);
   10597                 }
   10598                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10599                 mWindowManager.setAppFullscreen(token, false);
   10600                 return translucentChanged;
   10601             }
   10602         } finally {
   10603             Binder.restoreCallingIdentity(origId);
   10604         }
   10605     }
   10606 
   10607     @Override
   10608     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   10609         final long origId = Binder.clearCallingIdentity();
   10610         try {
   10611             synchronized (this) {
   10612                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10613                 if (r != null) {
   10614                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   10615                 }
   10616             }
   10617             return false;
   10618         } finally {
   10619             Binder.restoreCallingIdentity(origId);
   10620         }
   10621     }
   10622 
   10623     @Override
   10624     public boolean isBackgroundVisibleBehind(IBinder token) {
   10625         final long origId = Binder.clearCallingIdentity();
   10626         try {
   10627             synchronized (this) {
   10628                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   10629                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   10630                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
   10631                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   10632                 return visible;
   10633             }
   10634         } finally {
   10635             Binder.restoreCallingIdentity(origId);
   10636         }
   10637     }
   10638 
   10639     @Override
   10640     public ActivityOptions getActivityOptions(IBinder token) {
   10641         final long origId = Binder.clearCallingIdentity();
   10642         try {
   10643             synchronized (this) {
   10644                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10645                 if (r != null) {
   10646                     final ActivityOptions activityOptions = r.pendingOptions;
   10647                     r.pendingOptions = null;
   10648                     return activityOptions;
   10649                 }
   10650                 return null;
   10651             }
   10652         } finally {
   10653             Binder.restoreCallingIdentity(origId);
   10654         }
   10655     }
   10656 
   10657     @Override
   10658     public void setImmersive(IBinder token, boolean immersive) {
   10659         synchronized(this) {
   10660             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10661             if (r == null) {
   10662                 throw new IllegalArgumentException();
   10663             }
   10664             r.immersive = immersive;
   10665 
   10666             // update associated state if we're frontmost
   10667             if (r == mFocusedActivity) {
   10668                 if (DEBUG_IMMERSIVE) {
   10669                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   10670                 }
   10671                 applyUpdateLockStateLocked(r);
   10672             }
   10673         }
   10674     }
   10675 
   10676     @Override
   10677     public boolean isImmersive(IBinder token) {
   10678         synchronized (this) {
   10679             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10680             if (r == null) {
   10681                 throw new IllegalArgumentException();
   10682             }
   10683             return r.immersive;
   10684         }
   10685     }
   10686 
   10687     public boolean isTopActivityImmersive() {
   10688         enforceNotIsolatedCaller("startActivity");
   10689         synchronized (this) {
   10690             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
   10691             return (r != null) ? r.immersive : false;
   10692         }
   10693     }
   10694 
   10695     @Override
   10696     public boolean isTopOfTask(IBinder token) {
   10697         synchronized (this) {
   10698             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10699             if (r == null) {
   10700                 throw new IllegalArgumentException();
   10701             }
   10702             return r.task.getTopActivity() == r;
   10703         }
   10704     }
   10705 
   10706     public final void enterSafeMode() {
   10707         synchronized(this) {
   10708             // It only makes sense to do this before the system is ready
   10709             // and started launching other packages.
   10710             if (!mSystemReady) {
   10711                 try {
   10712                     AppGlobals.getPackageManager().enterSafeMode();
   10713                 } catch (RemoteException e) {
   10714                 }
   10715             }
   10716 
   10717             mSafeMode = true;
   10718         }
   10719     }
   10720 
   10721     public final void showSafeModeOverlay() {
   10722         View v = LayoutInflater.from(mContext).inflate(
   10723                 com.android.internal.R.layout.safe_mode, null);
   10724         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   10725         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   10726         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   10727         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   10728         lp.gravity = Gravity.BOTTOM | Gravity.START;
   10729         lp.format = v.getBackground().getOpacity();
   10730         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   10731                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   10732         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   10733         ((WindowManager)mContext.getSystemService(
   10734                 Context.WINDOW_SERVICE)).addView(v, lp);
   10735     }
   10736 
   10737     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
   10738         if (!(sender instanceof PendingIntentRecord)) {
   10739             return;
   10740         }
   10741         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10742         synchronized (stats) {
   10743             if (mBatteryStatsService.isOnBattery()) {
   10744                 mBatteryStatsService.enforceCallingPermission();
   10745                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   10746                 int MY_UID = Binder.getCallingUid();
   10747                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   10748                 BatteryStatsImpl.Uid.Pkg pkg =
   10749                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   10750                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   10751                 pkg.incWakeupsLocked();
   10752             }
   10753         }
   10754     }
   10755 
   10756     public boolean killPids(int[] pids, String pReason, boolean secure) {
   10757         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10758             throw new SecurityException("killPids only available to the system");
   10759         }
   10760         String reason = (pReason == null) ? "Unknown" : pReason;
   10761         // XXX Note: don't acquire main activity lock here, because the window
   10762         // manager calls in with its locks held.
   10763 
   10764         boolean killed = false;
   10765         synchronized (mPidsSelfLocked) {
   10766             int[] types = new int[pids.length];
   10767             int worstType = 0;
   10768             for (int i=0; i<pids.length; i++) {
   10769                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10770                 if (proc != null) {
   10771                     int type = proc.setAdj;
   10772                     types[i] = type;
   10773                     if (type > worstType) {
   10774                         worstType = type;
   10775                     }
   10776                 }
   10777             }
   10778 
   10779             // If the worst oom_adj is somewhere in the cached proc LRU range,
   10780             // then constrain it so we will kill all cached procs.
   10781             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   10782                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   10783                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   10784             }
   10785 
   10786             // If this is not a secure call, don't let it kill processes that
   10787             // are important.
   10788             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   10789                 worstType = ProcessList.SERVICE_ADJ;
   10790             }
   10791 
   10792             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   10793             for (int i=0; i<pids.length; i++) {
   10794                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10795                 if (proc == null) {
   10796                     continue;
   10797                 }
   10798                 int adj = proc.setAdj;
   10799                 if (adj >= worstType && !proc.killedByAm) {
   10800                     proc.kill(reason, true);
   10801                     killed = true;
   10802                 }
   10803             }
   10804         }
   10805         return killed;
   10806     }
   10807 
   10808     @Override
   10809     public void killUid(int uid, String reason) {
   10810         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10811             throw new SecurityException("killUid only available to the system");
   10812         }
   10813         synchronized (this) {
   10814             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   10815                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   10816                     reason != null ? reason : "kill uid");
   10817         }
   10818     }
   10819 
   10820     @Override
   10821     public boolean killProcessesBelowForeground(String reason) {
   10822         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10823             throw new SecurityException("killProcessesBelowForeground() only available to system");
   10824         }
   10825 
   10826         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   10827     }
   10828 
   10829     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   10830         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10831             throw new SecurityException("killProcessesBelowAdj() only available to system");
   10832         }
   10833 
   10834         boolean killed = false;
   10835         synchronized (mPidsSelfLocked) {
   10836             final int size = mPidsSelfLocked.size();
   10837             for (int i = 0; i < size; i++) {
   10838                 final int pid = mPidsSelfLocked.keyAt(i);
   10839                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   10840                 if (proc == null) continue;
   10841 
   10842                 final int adj = proc.setAdj;
   10843                 if (adj > belowAdj && !proc.killedByAm) {
   10844                     proc.kill(reason, true);
   10845                     killed = true;
   10846                 }
   10847             }
   10848         }
   10849         return killed;
   10850     }
   10851 
   10852     @Override
   10853     public void hang(final IBinder who, boolean allowRestart) {
   10854         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10855                 != PackageManager.PERMISSION_GRANTED) {
   10856             throw new SecurityException("Requires permission "
   10857                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10858         }
   10859 
   10860         final IBinder.DeathRecipient death = new DeathRecipient() {
   10861             @Override
   10862             public void binderDied() {
   10863                 synchronized (this) {
   10864                     notifyAll();
   10865                 }
   10866             }
   10867         };
   10868 
   10869         try {
   10870             who.linkToDeath(death, 0);
   10871         } catch (RemoteException e) {
   10872             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   10873             return;
   10874         }
   10875 
   10876         synchronized (this) {
   10877             Watchdog.getInstance().setAllowRestart(allowRestart);
   10878             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   10879             synchronized (death) {
   10880                 while (who.isBinderAlive()) {
   10881                     try {
   10882                         death.wait();
   10883                     } catch (InterruptedException e) {
   10884                     }
   10885                 }
   10886             }
   10887             Watchdog.getInstance().setAllowRestart(true);
   10888         }
   10889     }
   10890 
   10891     @Override
   10892     public void restart() {
   10893         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10894                 != PackageManager.PERMISSION_GRANTED) {
   10895             throw new SecurityException("Requires permission "
   10896                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10897         }
   10898 
   10899         Log.i(TAG, "Sending shutdown broadcast...");
   10900 
   10901         BroadcastReceiver br = new BroadcastReceiver() {
   10902             @Override public void onReceive(Context context, Intent intent) {
   10903                 // Now the broadcast is done, finish up the low-level shutdown.
   10904                 Log.i(TAG, "Shutting down activity manager...");
   10905                 shutdown(10000);
   10906                 Log.i(TAG, "Shutdown complete, restarting!");
   10907                 Process.killProcess(Process.myPid());
   10908                 System.exit(10);
   10909             }
   10910         };
   10911 
   10912         // First send the high-level shut down broadcast.
   10913         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   10914         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   10915         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   10916         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   10917         mContext.sendOrderedBroadcastAsUser(intent,
   10918                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   10919         */
   10920         br.onReceive(mContext, intent);
   10921     }
   10922 
   10923     private long getLowRamTimeSinceIdle(long now) {
   10924         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   10925     }
   10926 
   10927     @Override
   10928     public void performIdleMaintenance() {
   10929         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10930                 != PackageManager.PERMISSION_GRANTED) {
   10931             throw new SecurityException("Requires permission "
   10932                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10933         }
   10934 
   10935         synchronized (this) {
   10936             final long now = SystemClock.uptimeMillis();
   10937             final long timeSinceLastIdle = now - mLastIdleTime;
   10938             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   10939             mLastIdleTime = now;
   10940             mLowRamTimeSinceLastIdle = 0;
   10941             if (mLowRamStartTime != 0) {
   10942                 mLowRamStartTime = now;
   10943             }
   10944 
   10945             StringBuilder sb = new StringBuilder(128);
   10946             sb.append("Idle maintenance over ");
   10947             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   10948             sb.append(" low RAM for ");
   10949             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   10950             Slog.i(TAG, sb.toString());
   10951 
   10952             // If at least 1/3 of our time since the last idle period has been spent
   10953             // with RAM low, then we want to kill processes.
   10954             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   10955 
   10956             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   10957                 ProcessRecord proc = mLruProcesses.get(i);
   10958                 if (proc.notCachedSinceIdle) {
   10959                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
   10960                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   10961                         if (doKilling && proc.initialIdlePss != 0
   10962                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   10963                             sb = new StringBuilder(128);
   10964                             sb.append("Kill");
   10965                             sb.append(proc.processName);
   10966                             sb.append(" in idle maint: pss=");
   10967                             sb.append(proc.lastPss);
   10968                             sb.append(", initialPss=");
   10969                             sb.append(proc.initialIdlePss);
   10970                             sb.append(", period=");
   10971                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   10972                             sb.append(", lowRamPeriod=");
   10973                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   10974                             Slog.wtfQuiet(TAG, sb.toString());
   10975                             proc.kill("idle maint (pss " + proc.lastPss
   10976                                     + " from " + proc.initialIdlePss + ")", true);
   10977                         }
   10978                     }
   10979                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
   10980                     proc.notCachedSinceIdle = true;
   10981                     proc.initialIdlePss = 0;
   10982                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
   10983                             mTestPssMode, isSleeping(), now);
   10984                 }
   10985             }
   10986 
   10987             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   10988             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   10989         }
   10990     }
   10991 
   10992     private void retrieveSettings() {
   10993         final ContentResolver resolver = mContext.getContentResolver();
   10994         String debugApp = Settings.Global.getString(
   10995             resolver, Settings.Global.DEBUG_APP);
   10996         boolean waitForDebugger = Settings.Global.getInt(
   10997             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   10998         boolean alwaysFinishActivities = Settings.Global.getInt(
   10999             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   11000         boolean forceRtl = Settings.Global.getInt(
   11001                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
   11002         // Transfer any global setting for forcing RTL layout, into a System Property
   11003         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   11004 
   11005         Configuration configuration = new Configuration();
   11006         Settings.System.getConfiguration(resolver, configuration);
   11007         if (forceRtl) {
   11008             // This will take care of setting the correct layout direction flags
   11009             configuration.setLayoutDirection(configuration.locale);
   11010         }
   11011 
   11012         synchronized (this) {
   11013             mDebugApp = mOrigDebugApp = debugApp;
   11014             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   11015             mAlwaysFinishActivities = alwaysFinishActivities;
   11016             // This happens before any activities are started, so we can
   11017             // change mConfiguration in-place.
   11018             updateConfigurationLocked(configuration, null, false, true);
   11019             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   11020         }
   11021     }
   11022 
   11023     /** Loads resources after the current configuration has been set. */
   11024     private void loadResourcesOnSystemReady() {
   11025         final Resources res = mContext.getResources();
   11026         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   11027         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
   11028         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
   11029     }
   11030 
   11031     public boolean testIsSystemReady() {
   11032         // no need to synchronize(this) just to read & return the value
   11033         return mSystemReady;
   11034     }
   11035 
   11036     private static File getCalledPreBootReceiversFile() {
   11037         File dataDir = Environment.getDataDirectory();
   11038         File systemDir = new File(dataDir, "system");
   11039         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
   11040         return fname;
   11041     }
   11042 
   11043     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   11044         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   11045         File file = getCalledPreBootReceiversFile();
   11046         FileInputStream fis = null;
   11047         try {
   11048             fis = new FileInputStream(file);
   11049             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   11050             int fvers = dis.readInt();
   11051             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
   11052                 String vers = dis.readUTF();
   11053                 String codename = dis.readUTF();
   11054                 String build = dis.readUTF();
   11055                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   11056                         && android.os.Build.VERSION.CODENAME.equals(codename)
   11057                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   11058                     int num = dis.readInt();
   11059                     while (num > 0) {
   11060                         num--;
   11061                         String pkg = dis.readUTF();
   11062                         String cls = dis.readUTF();
   11063                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   11064                     }
   11065                 }
   11066             }
   11067         } catch (FileNotFoundException e) {
   11068         } catch (IOException e) {
   11069             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   11070         } finally {
   11071             if (fis != null) {
   11072                 try {
   11073                     fis.close();
   11074                 } catch (IOException e) {
   11075                 }
   11076             }
   11077         }
   11078         return lastDoneReceivers;
   11079     }
   11080 
   11081     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   11082         File file = getCalledPreBootReceiversFile();
   11083         FileOutputStream fos = null;
   11084         DataOutputStream dos = null;
   11085         try {
   11086             fos = new FileOutputStream(file);
   11087             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   11088             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
   11089             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   11090             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   11091             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   11092             dos.writeInt(list.size());
   11093             for (int i=0; i<list.size(); i++) {
   11094                 dos.writeUTF(list.get(i).getPackageName());
   11095                 dos.writeUTF(list.get(i).getClassName());
   11096             }
   11097         } catch (IOException e) {
   11098             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   11099             file.delete();
   11100         } finally {
   11101             FileUtils.sync(fos);
   11102             if (dos != null) {
   11103                 try {
   11104                     dos.close();
   11105                 } catch (IOException e) {
   11106                     // TODO Auto-generated catch block
   11107                     e.printStackTrace();
   11108                 }
   11109             }
   11110         }
   11111     }
   11112 
   11113     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
   11114             ArrayList<ComponentName> doneReceivers, int userId) {
   11115         boolean waitingUpdate = false;
   11116         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   11117         List<ResolveInfo> ris = null;
   11118         try {
   11119             ris = AppGlobals.getPackageManager().queryIntentReceivers(
   11120                     intent, null, 0, userId);
   11121         } catch (RemoteException e) {
   11122         }
   11123         if (ris != null) {
   11124             for (int i=ris.size()-1; i>=0; i--) {
   11125                 if ((ris.get(i).activityInfo.applicationInfo.flags
   11126                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
   11127                     ris.remove(i);
   11128                 }
   11129             }
   11130             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   11131 
   11132             // For User 0, load the version number. When delivering to a new user, deliver
   11133             // to all receivers.
   11134             if (userId == UserHandle.USER_OWNER) {
   11135                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   11136                 for (int i=0; i<ris.size(); i++) {
   11137                     ActivityInfo ai = ris.get(i).activityInfo;
   11138                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11139                     if (lastDoneReceivers.contains(comp)) {
   11140                         // We already did the pre boot receiver for this app with the current
   11141                         // platform version, so don't do it again...
   11142                         ris.remove(i);
   11143                         i--;
   11144                         // ...however, do keep it as one that has been done, so we don't
   11145                         // forget about it when rewriting the file of last done receivers.
   11146                         doneReceivers.add(comp);
   11147                     }
   11148                 }
   11149             }
   11150 
   11151             // If primary user, send broadcast to all available users, else just to userId
   11152             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
   11153                     : new int[] { userId };
   11154             for (int i = 0; i < ris.size(); i++) {
   11155                 ActivityInfo ai = ris.get(i).activityInfo;
   11156                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11157                 doneReceivers.add(comp);
   11158                 intent.setComponent(comp);
   11159                 for (int j=0; j<users.length; j++) {
   11160                     IIntentReceiver finisher = null;
   11161                     // On last receiver and user, set up a completion callback
   11162                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
   11163                         finisher = new IIntentReceiver.Stub() {
   11164                             public void performReceive(Intent intent, int resultCode,
   11165                                     String data, Bundle extras, boolean ordered,
   11166                                     boolean sticky, int sendingUser) {
   11167                                 // The raw IIntentReceiver interface is called
   11168                                 // with the AM lock held, so redispatch to
   11169                                 // execute our code without the lock.
   11170                                 mHandler.post(onFinishCallback);
   11171                             }
   11172                         };
   11173                     }
   11174                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
   11175                             + " for user " + users[j]);
   11176                     broadcastIntentLocked(null, null, intent, null, finisher,
   11177                             0, null, null, null, AppOpsManager.OP_NONE,
   11178                             true, false, MY_PID, Process.SYSTEM_UID,
   11179                             users[j]);
   11180                     if (finisher != null) {
   11181                         waitingUpdate = true;
   11182                     }
   11183                 }
   11184             }
   11185         }
   11186 
   11187         return waitingUpdate;
   11188     }
   11189 
   11190     public void systemReady(final Runnable goingCallback) {
   11191         synchronized(this) {
   11192             if (mSystemReady) {
   11193                 // If we're done calling all the receivers, run the next "boot phase" passed in
   11194                 // by the SystemServer
   11195                 if (goingCallback != null) {
   11196                     goingCallback.run();
   11197                 }
   11198                 return;
   11199             }
   11200 
   11201             // Make sure we have the current profile info, since it is needed for
   11202             // security checks.
   11203             updateCurrentProfileIdsLocked();
   11204 
   11205             if (mRecentTasks == null) {
   11206                 mRecentTasks = mTaskPersister.restoreTasksLocked();
   11207                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
   11208                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
   11209                 mTaskPersister.startPersisting();
   11210             }
   11211 
   11212             // Check to see if there are any update receivers to run.
   11213             if (!mDidUpdate) {
   11214                 if (mWaitingUpdate) {
   11215                     return;
   11216                 }
   11217                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   11218                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
   11219                     public void run() {
   11220                         synchronized (ActivityManagerService.this) {
   11221                             mDidUpdate = true;
   11222                         }
   11223                         writeLastDonePreBootReceivers(doneReceivers);
   11224                         showBootMessage(mContext.getText(R.string.android_upgrading_complete),
   11225                                 false);
   11226                         systemReady(goingCallback);
   11227                     }
   11228                 }, doneReceivers, UserHandle.USER_OWNER);
   11229 
   11230                 if (mWaitingUpdate) {
   11231                     return;
   11232                 }
   11233                 mDidUpdate = true;
   11234             }
   11235 
   11236             mAppOpsService.systemReady();
   11237             mSystemReady = true;
   11238         }
   11239 
   11240         ArrayList<ProcessRecord> procsToKill = null;
   11241         synchronized(mPidsSelfLocked) {
   11242             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   11243                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   11244                 if (!isAllowedWhileBooting(proc.info)){
   11245                     if (procsToKill == null) {
   11246                         procsToKill = new ArrayList<ProcessRecord>();
   11247                     }
   11248                     procsToKill.add(proc);
   11249                 }
   11250             }
   11251         }
   11252 
   11253         synchronized(this) {
   11254             if (procsToKill != null) {
   11255                 for (int i=procsToKill.size()-1; i>=0; i--) {
   11256                     ProcessRecord proc = procsToKill.get(i);
   11257                     Slog.i(TAG, "Removing system update proc: " + proc);
   11258                     removeProcessLocked(proc, true, false, "system update done");
   11259                 }
   11260             }
   11261 
   11262             // Now that we have cleaned up any update processes, we
   11263             // are ready to start launching real processes and know that
   11264             // we won't trample on them any more.
   11265             mProcessesReady = true;
   11266         }
   11267 
   11268         Slog.i(TAG, "System now ready");
   11269         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   11270             SystemClock.uptimeMillis());
   11271 
   11272         synchronized(this) {
   11273             // Make sure we have no pre-ready processes sitting around.
   11274 
   11275             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11276                 ResolveInfo ri = mContext.getPackageManager()
   11277                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   11278                                 STOCK_PM_FLAGS);
   11279                 CharSequence errorMsg = null;
   11280                 if (ri != null) {
   11281                     ActivityInfo ai = ri.activityInfo;
   11282                     ApplicationInfo app = ai.applicationInfo;
   11283                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   11284                         mTopAction = Intent.ACTION_FACTORY_TEST;
   11285                         mTopData = null;
   11286                         mTopComponent = new ComponentName(app.packageName,
   11287                                 ai.name);
   11288                     } else {
   11289                         errorMsg = mContext.getResources().getText(
   11290                                 com.android.internal.R.string.factorytest_not_system);
   11291                     }
   11292                 } else {
   11293                     errorMsg = mContext.getResources().getText(
   11294                             com.android.internal.R.string.factorytest_no_action);
   11295                 }
   11296                 if (errorMsg != null) {
   11297                     mTopAction = null;
   11298                     mTopData = null;
   11299                     mTopComponent = null;
   11300                     Message msg = Message.obtain();
   11301                     msg.what = SHOW_FACTORY_ERROR_MSG;
   11302                     msg.getData().putCharSequence("msg", errorMsg);
   11303                     mHandler.sendMessage(msg);
   11304                 }
   11305             }
   11306         }
   11307 
   11308         retrieveSettings();
   11309         loadResourcesOnSystemReady();
   11310 
   11311         synchronized (this) {
   11312             readGrantedUriPermissionsLocked();
   11313         }
   11314 
   11315         if (goingCallback != null) goingCallback.run();
   11316 
   11317         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   11318                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11319         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   11320                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11321         mSystemServiceManager.startUser(mCurrentUserId);
   11322 
   11323         synchronized (this) {
   11324             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11325                 try {
   11326                     List apps = AppGlobals.getPackageManager().
   11327                         getPersistentApplications(STOCK_PM_FLAGS);
   11328                     if (apps != null) {
   11329                         int N = apps.size();
   11330                         int i;
   11331                         for (i=0; i<N; i++) {
   11332                             ApplicationInfo info
   11333                                 = (ApplicationInfo)apps.get(i);
   11334                             if (info != null &&
   11335                                     !info.packageName.equals("android")) {
   11336                                 addAppLocked(info, false, null /* ABI override */);
   11337                             }
   11338                         }
   11339                     }
   11340                 } catch (RemoteException ex) {
   11341                     // pm is in same process, this will never happen.
   11342                 }
   11343             }
   11344 
   11345             // Start up initial activity.
   11346             mBooting = true;
   11347             startHomeActivityLocked(mCurrentUserId, "systemReady");
   11348 
   11349             try {
   11350                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   11351                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   11352                             + " data partition or your device will be unstable.");
   11353                     mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
   11354                 }
   11355             } catch (RemoteException e) {
   11356             }
   11357 
   11358             if (!Build.isFingerprintConsistent()) {
   11359                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   11360                 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
   11361             }
   11362 
   11363             long ident = Binder.clearCallingIdentity();
   11364             try {
   11365                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   11366                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   11367                         | Intent.FLAG_RECEIVER_FOREGROUND);
   11368                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11369                 broadcastIntentLocked(null, null, intent,
   11370                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   11371                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   11372                 intent = new Intent(Intent.ACTION_USER_STARTING);
   11373                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   11374                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11375                 broadcastIntentLocked(null, null, intent,
   11376                         null, new IIntentReceiver.Stub() {
   11377                             @Override
   11378                             public void performReceive(Intent intent, int resultCode, String data,
   11379                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   11380                                     throws RemoteException {
   11381                             }
   11382                         }, 0, null, null,
   11383                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   11384                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   11385             } catch (Throwable t) {
   11386                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   11387             } finally {
   11388                 Binder.restoreCallingIdentity(ident);
   11389             }
   11390             mStackSupervisor.resumeTopActivitiesLocked();
   11391             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   11392         }
   11393     }
   11394 
   11395     private boolean makeAppCrashingLocked(ProcessRecord app,
   11396             String shortMsg, String longMsg, String stackTrace) {
   11397         app.crashing = true;
   11398         app.crashingReport = generateProcessError(app,
   11399                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   11400         startAppProblemLocked(app);
   11401         app.stopFreezingAllLocked();
   11402         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
   11403     }
   11404 
   11405     private void makeAppNotRespondingLocked(ProcessRecord app,
   11406             String activity, String shortMsg, String longMsg) {
   11407         app.notResponding = true;
   11408         app.notRespondingReport = generateProcessError(app,
   11409                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   11410                 activity, shortMsg, longMsg, null);
   11411         startAppProblemLocked(app);
   11412         app.stopFreezingAllLocked();
   11413     }
   11414 
   11415     /**
   11416      * Generate a process error record, suitable for attachment to a ProcessRecord.
   11417      *
   11418      * @param app The ProcessRecord in which the error occurred.
   11419      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   11420      *                      ActivityManager.AppErrorStateInfo
   11421      * @param activity The activity associated with the crash, if known.
   11422      * @param shortMsg Short message describing the crash.
   11423      * @param longMsg Long message describing the crash.
   11424      * @param stackTrace Full crash stack trace, may be null.
   11425      *
   11426      * @return Returns a fully-formed AppErrorStateInfo record.
   11427      */
   11428     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   11429             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   11430         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   11431 
   11432         report.condition = condition;
   11433         report.processName = app.processName;
   11434         report.pid = app.pid;
   11435         report.uid = app.info.uid;
   11436         report.tag = activity;
   11437         report.shortMsg = shortMsg;
   11438         report.longMsg = longMsg;
   11439         report.stackTrace = stackTrace;
   11440 
   11441         return report;
   11442     }
   11443 
   11444     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   11445         synchronized (this) {
   11446             app.crashing = false;
   11447             app.crashingReport = null;
   11448             app.notResponding = false;
   11449             app.notRespondingReport = null;
   11450             if (app.anrDialog == fromDialog) {
   11451                 app.anrDialog = null;
   11452             }
   11453             if (app.waitDialog == fromDialog) {
   11454                 app.waitDialog = null;
   11455             }
   11456             if (app.pid > 0 && app.pid != MY_PID) {
   11457                 handleAppCrashLocked(app, null, null, null);
   11458                 app.kill("user request after error", true);
   11459             }
   11460         }
   11461     }
   11462 
   11463     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
   11464             String stackTrace) {
   11465         long now = SystemClock.uptimeMillis();
   11466 
   11467         Long crashTime;
   11468         if (!app.isolated) {
   11469             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   11470         } else {
   11471             crashTime = null;
   11472         }
   11473         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   11474             // This process loses!
   11475             Slog.w(TAG, "Process " + app.info.processName
   11476                     + " has crashed too many times: killing!");
   11477             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   11478                     app.userId, app.info.processName, app.uid);
   11479             mStackSupervisor.handleAppCrashLocked(app);
   11480             if (!app.persistent) {
   11481                 // We don't want to start this process again until the user
   11482                 // explicitly does so...  but for persistent process, we really
   11483                 // need to keep it running.  If a persistent process is actually
   11484                 // repeatedly crashing, then badness for everyone.
   11485                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   11486                         app.info.processName);
   11487                 if (!app.isolated) {
   11488                     // XXX We don't have a way to mark isolated processes
   11489                     // as bad, since they don't have a peristent identity.
   11490                     mBadProcesses.put(app.info.processName, app.uid,
   11491                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
   11492                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   11493                 }
   11494                 app.bad = true;
   11495                 app.removed = true;
   11496                 // Don't let services in this process be restarted and potentially
   11497                 // annoy the user repeatedly.  Unless it is persistent, since those
   11498                 // processes run critical code.
   11499                 removeProcessLocked(app, false, false, "crash");
   11500                 mStackSupervisor.resumeTopActivitiesLocked();
   11501                 return false;
   11502             }
   11503             mStackSupervisor.resumeTopActivitiesLocked();
   11504         } else {
   11505             mStackSupervisor.finishTopRunningActivityLocked(app);
   11506         }
   11507 
   11508         // Bump up the crash count of any services currently running in the proc.
   11509         for (int i=app.services.size()-1; i>=0; i--) {
   11510             // Any services running in the application need to be placed
   11511             // back in the pending list.
   11512             ServiceRecord sr = app.services.valueAt(i);
   11513             sr.crashCount++;
   11514         }
   11515 
   11516         // If the crashing process is what we consider to be the "home process" and it has been
   11517         // replaced by a third-party app, clear the package preferred activities from packages
   11518         // with a home activity running in the process to prevent a repeatedly crashing app
   11519         // from blocking the user to manually clear the list.
   11520         final ArrayList<ActivityRecord> activities = app.activities;
   11521         if (app == mHomeProcess && activities.size() > 0
   11522                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   11523             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   11524                 final ActivityRecord r = activities.get(activityNdx);
   11525                 if (r.isHomeActivity()) {
   11526                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   11527                     try {
   11528                         ActivityThread.getPackageManager()
   11529                                 .clearPackagePreferredActivities(r.packageName);
   11530                     } catch (RemoteException c) {
   11531                         // pm is in same process, this will never happen.
   11532                     }
   11533                 }
   11534             }
   11535         }
   11536 
   11537         if (!app.isolated) {
   11538             // XXX Can't keep track of crash times for isolated processes,
   11539             // because they don't have a perisistent identity.
   11540             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   11541         }
   11542 
   11543         if (app.crashHandler != null) mHandler.post(app.crashHandler);
   11544         return true;
   11545     }
   11546 
   11547     void startAppProblemLocked(ProcessRecord app) {
   11548         // If this app is not running under the current user, then we
   11549         // can't give it a report button because that would require
   11550         // launching the report UI under a different user.
   11551         app.errorReportReceiver = null;
   11552 
   11553         for (int userId : mCurrentProfileIds) {
   11554             if (app.userId == userId) {
   11555                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   11556                         mContext, app.info.packageName, app.info.flags);
   11557             }
   11558         }
   11559         skipCurrentReceiverLocked(app);
   11560     }
   11561 
   11562     void skipCurrentReceiverLocked(ProcessRecord app) {
   11563         for (BroadcastQueue queue : mBroadcastQueues) {
   11564             queue.skipCurrentReceiverLocked(app);
   11565         }
   11566     }
   11567 
   11568     /**
   11569      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   11570      * The application process will exit immediately after this call returns.
   11571      * @param app object of the crashing app, null for the system server
   11572      * @param crashInfo describing the exception
   11573      */
   11574     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   11575         ProcessRecord r = findAppProcess(app, "Crash");
   11576         final String processName = app == null ? "system_server"
   11577                 : (r == null ? "unknown" : r.processName);
   11578 
   11579         handleApplicationCrashInner("crash", r, processName, crashInfo);
   11580     }
   11581 
   11582     /* Native crash reporting uses this inner version because it needs to be somewhat
   11583      * decoupled from the AM-managed cleanup lifecycle
   11584      */
   11585     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   11586             ApplicationErrorReport.CrashInfo crashInfo) {
   11587         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   11588                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   11589                 r == null ? -1 : r.info.flags,
   11590                 crashInfo.exceptionClassName,
   11591                 crashInfo.exceptionMessage,
   11592                 crashInfo.throwFileName,
   11593                 crashInfo.throwLineNumber);
   11594 
   11595         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   11596 
   11597         crashApplication(r, crashInfo);
   11598     }
   11599 
   11600     public void handleApplicationStrictModeViolation(
   11601             IBinder app,
   11602             int violationMask,
   11603             StrictMode.ViolationInfo info) {
   11604         ProcessRecord r = findAppProcess(app, "StrictMode");
   11605         if (r == null) {
   11606             return;
   11607         }
   11608 
   11609         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   11610             Integer stackFingerprint = info.hashCode();
   11611             boolean logIt = true;
   11612             synchronized (mAlreadyLoggedViolatedStacks) {
   11613                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   11614                     logIt = false;
   11615                     // TODO: sub-sample into EventLog for these, with
   11616                     // the info.durationMillis?  Then we'd get
   11617                     // the relative pain numbers, without logging all
   11618                     // the stack traces repeatedly.  We'd want to do
   11619                     // likewise in the client code, which also does
   11620                     // dup suppression, before the Binder call.
   11621                 } else {
   11622                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   11623                         mAlreadyLoggedViolatedStacks.clear();
   11624                     }
   11625                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   11626                 }
   11627             }
   11628             if (logIt) {
   11629                 logStrictModeViolationToDropBox(r, info);
   11630             }
   11631         }
   11632 
   11633         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   11634             AppErrorResult result = new AppErrorResult();
   11635             synchronized (this) {
   11636                 final long origId = Binder.clearCallingIdentity();
   11637 
   11638                 Message msg = Message.obtain();
   11639                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   11640                 HashMap<String, Object> data = new HashMap<String, Object>();
   11641                 data.put("result", result);
   11642                 data.put("app", r);
   11643                 data.put("violationMask", violationMask);
   11644                 data.put("info", info);
   11645                 msg.obj = data;
   11646                 mHandler.sendMessage(msg);
   11647 
   11648                 Binder.restoreCallingIdentity(origId);
   11649             }
   11650             int res = result.get();
   11651             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   11652         }
   11653     }
   11654 
   11655     // Depending on the policy in effect, there could be a bunch of
   11656     // these in quick succession so we try to batch these together to
   11657     // minimize disk writes, number of dropbox entries, and maximize
   11658     // compression, by having more fewer, larger records.
   11659     private void logStrictModeViolationToDropBox(
   11660             ProcessRecord process,
   11661             StrictMode.ViolationInfo info) {
   11662         if (info == null) {
   11663             return;
   11664         }
   11665         final boolean isSystemApp = process == null ||
   11666                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   11667                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   11668         final String processName = process == null ? "unknown" : process.processName;
   11669         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   11670         final DropBoxManager dbox = (DropBoxManager)
   11671                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11672 
   11673         // Exit early if the dropbox isn't configured to accept this report type.
   11674         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11675 
   11676         boolean bufferWasEmpty;
   11677         boolean needsFlush;
   11678         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   11679         synchronized (sb) {
   11680             bufferWasEmpty = sb.length() == 0;
   11681             appendDropBoxProcessHeaders(process, processName, sb);
   11682             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11683             sb.append("System-App: ").append(isSystemApp).append("\n");
   11684             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   11685             if (info.violationNumThisLoop != 0) {
   11686                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   11687             }
   11688             if (info.numAnimationsRunning != 0) {
   11689                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   11690             }
   11691             if (info.broadcastIntentAction != null) {
   11692                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   11693             }
   11694             if (info.durationMillis != -1) {
   11695                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   11696             }
   11697             if (info.numInstances != -1) {
   11698                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   11699             }
   11700             if (info.tags != null) {
   11701                 for (String tag : info.tags) {
   11702                     sb.append("Span-Tag: ").append(tag).append("\n");
   11703                 }
   11704             }
   11705             sb.append("\n");
   11706             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   11707                 sb.append(info.crashInfo.stackTrace);
   11708             }
   11709             sb.append("\n");
   11710 
   11711             // Only buffer up to ~64k.  Various logging bits truncate
   11712             // things at 128k.
   11713             needsFlush = (sb.length() > 64 * 1024);
   11714         }
   11715 
   11716         // Flush immediately if the buffer's grown too large, or this
   11717         // is a non-system app.  Non-system apps are isolated with a
   11718         // different tag & policy and not batched.
   11719         //
   11720         // Batching is useful during internal testing with
   11721         // StrictMode settings turned up high.  Without batching,
   11722         // thousands of separate files could be created on boot.
   11723         if (!isSystemApp || needsFlush) {
   11724             new Thread("Error dump: " + dropboxTag) {
   11725                 @Override
   11726                 public void run() {
   11727                     String report;
   11728                     synchronized (sb) {
   11729                         report = sb.toString();
   11730                         sb.delete(0, sb.length());
   11731                         sb.trimToSize();
   11732                     }
   11733                     if (report.length() != 0) {
   11734                         dbox.addText(dropboxTag, report);
   11735                     }
   11736                 }
   11737             }.start();
   11738             return;
   11739         }
   11740 
   11741         // System app batching:
   11742         if (!bufferWasEmpty) {
   11743             // An existing dropbox-writing thread is outstanding, so
   11744             // we don't need to start it up.  The existing thread will
   11745             // catch the buffer appends we just did.
   11746             return;
   11747         }
   11748 
   11749         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   11750         // (After this point, we shouldn't access AMS internal data structures.)
   11751         new Thread("Error dump: " + dropboxTag) {
   11752             @Override
   11753             public void run() {
   11754                 // 5 second sleep to let stacks arrive and be batched together
   11755                 try {
   11756                     Thread.sleep(5000);  // 5 seconds
   11757                 } catch (InterruptedException e) {}
   11758 
   11759                 String errorReport;
   11760                 synchronized (mStrictModeBuffer) {
   11761                     errorReport = mStrictModeBuffer.toString();
   11762                     if (errorReport.length() == 0) {
   11763                         return;
   11764                     }
   11765                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   11766                     mStrictModeBuffer.trimToSize();
   11767                 }
   11768                 dbox.addText(dropboxTag, errorReport);
   11769             }
   11770         }.start();
   11771     }
   11772 
   11773     /**
   11774      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   11775      * @param app object of the crashing app, null for the system server
   11776      * @param tag reported by the caller
   11777      * @param system whether this wtf is coming from the system
   11778      * @param crashInfo describing the context of the error
   11779      * @return true if the process should exit immediately (WTF is fatal)
   11780      */
   11781     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   11782             final ApplicationErrorReport.CrashInfo crashInfo) {
   11783         final int callingUid = Binder.getCallingUid();
   11784         final int callingPid = Binder.getCallingPid();
   11785 
   11786         if (system) {
   11787             // If this is coming from the system, we could very well have low-level
   11788             // system locks held, so we want to do this all asynchronously.  And we
   11789             // never want this to become fatal, so there is that too.
   11790             mHandler.post(new Runnable() {
   11791                 @Override public void run() {
   11792                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   11793                 }
   11794             });
   11795             return false;
   11796         }
   11797 
   11798         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   11799                 crashInfo);
   11800 
   11801         if (r != null && r.pid != Process.myPid() &&
   11802                 Settings.Global.getInt(mContext.getContentResolver(),
   11803                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   11804             crashApplication(r, crashInfo);
   11805             return true;
   11806         } else {
   11807             return false;
   11808         }
   11809     }
   11810 
   11811     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   11812             final ApplicationErrorReport.CrashInfo crashInfo) {
   11813         final ProcessRecord r = findAppProcess(app, "WTF");
   11814         final String processName = app == null ? "system_server"
   11815                 : (r == null ? "unknown" : r.processName);
   11816 
   11817         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   11818                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   11819 
   11820         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   11821 
   11822         return r;
   11823     }
   11824 
   11825     /**
   11826      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   11827      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   11828      */
   11829     private ProcessRecord findAppProcess(IBinder app, String reason) {
   11830         if (app == null) {
   11831             return null;
   11832         }
   11833 
   11834         synchronized (this) {
   11835             final int NP = mProcessNames.getMap().size();
   11836             for (int ip=0; ip<NP; ip++) {
   11837                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11838                 final int NA = apps.size();
   11839                 for (int ia=0; ia<NA; ia++) {
   11840                     ProcessRecord p = apps.valueAt(ia);
   11841                     if (p.thread != null && p.thread.asBinder() == app) {
   11842                         return p;
   11843                     }
   11844                 }
   11845             }
   11846 
   11847             Slog.w(TAG, "Can't find mystery application for " + reason
   11848                     + " from pid=" + Binder.getCallingPid()
   11849                     + " uid=" + Binder.getCallingUid() + ": " + app);
   11850             return null;
   11851         }
   11852     }
   11853 
   11854     /**
   11855      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   11856      * to append various headers to the dropbox log text.
   11857      */
   11858     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   11859             StringBuilder sb) {
   11860         // Watchdog thread ends up invoking this function (with
   11861         // a null ProcessRecord) to add the stack file to dropbox.
   11862         // Do not acquire a lock on this (am) in such cases, as it
   11863         // could cause a potential deadlock, if and when watchdog
   11864         // is invoked due to unavailability of lock on am and it
   11865         // would prevent watchdog from killing system_server.
   11866         if (process == null) {
   11867             sb.append("Process: ").append(processName).append("\n");
   11868             return;
   11869         }
   11870         // Note: ProcessRecord 'process' is guarded by the service
   11871         // instance.  (notably process.pkgList, which could otherwise change
   11872         // concurrently during execution of this method)
   11873         synchronized (this) {
   11874             sb.append("Process: ").append(processName).append("\n");
   11875             int flags = process.info.flags;
   11876             IPackageManager pm = AppGlobals.getPackageManager();
   11877             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   11878             for (int ip=0; ip<process.pkgList.size(); ip++) {
   11879                 String pkg = process.pkgList.keyAt(ip);
   11880                 sb.append("Package: ").append(pkg);
   11881                 try {
   11882                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   11883                     if (pi != null) {
   11884                         sb.append(" v").append(pi.versionCode);
   11885                         if (pi.versionName != null) {
   11886                             sb.append(" (").append(pi.versionName).append(")");
   11887                         }
   11888                     }
   11889                 } catch (RemoteException e) {
   11890                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   11891                 }
   11892                 sb.append("\n");
   11893             }
   11894         }
   11895     }
   11896 
   11897     private static String processClass(ProcessRecord process) {
   11898         if (process == null || process.pid == MY_PID) {
   11899             return "system_server";
   11900         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   11901             return "system_app";
   11902         } else {
   11903             return "data_app";
   11904         }
   11905     }
   11906 
   11907     /**
   11908      * Write a description of an error (crash, WTF, ANR) to the drop box.
   11909      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   11910      * @param process which caused the error, null means the system server
   11911      * @param activity which triggered the error, null if unknown
   11912      * @param parent activity related to the error, null if unknown
   11913      * @param subject line related to the error, null if absent
   11914      * @param report in long form describing the error, null if absent
   11915      * @param logFile to include in the report, null if none
   11916      * @param crashInfo giving an application stack trace, null if absent
   11917      */
   11918     public void addErrorToDropBox(String eventType,
   11919             ProcessRecord process, String processName, ActivityRecord activity,
   11920             ActivityRecord parent, String subject,
   11921             final String report, final File logFile,
   11922             final ApplicationErrorReport.CrashInfo crashInfo) {
   11923         // NOTE -- this must never acquire the ActivityManagerService lock,
   11924         // otherwise the watchdog may be prevented from resetting the system.
   11925 
   11926         final String dropboxTag = processClass(process) + "_" + eventType;
   11927         final DropBoxManager dbox = (DropBoxManager)
   11928                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11929 
   11930         // Exit early if the dropbox isn't configured to accept this report type.
   11931         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11932 
   11933         final StringBuilder sb = new StringBuilder(1024);
   11934         appendDropBoxProcessHeaders(process, processName, sb);
   11935         if (activity != null) {
   11936             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   11937         }
   11938         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   11939             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   11940         }
   11941         if (parent != null && parent != activity) {
   11942             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   11943         }
   11944         if (subject != null) {
   11945             sb.append("Subject: ").append(subject).append("\n");
   11946         }
   11947         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11948         if (Debug.isDebuggerConnected()) {
   11949             sb.append("Debugger: Connected\n");
   11950         }
   11951         sb.append("\n");
   11952 
   11953         // Do the rest in a worker thread to avoid blocking the caller on I/O
   11954         // (After this point, we shouldn't access AMS internal data structures.)
   11955         Thread worker = new Thread("Error dump: " + dropboxTag) {
   11956             @Override
   11957             public void run() {
   11958                 if (report != null) {
   11959                     sb.append(report);
   11960                 }
   11961                 if (logFile != null) {
   11962                     try {
   11963                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
   11964                                     "\n\n[[TRUNCATED]]"));
   11965                     } catch (IOException e) {
   11966                         Slog.e(TAG, "Error reading " + logFile, e);
   11967                     }
   11968                 }
   11969                 if (crashInfo != null && crashInfo.stackTrace != null) {
   11970                     sb.append(crashInfo.stackTrace);
   11971                 }
   11972 
   11973                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   11974                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   11975                 if (lines > 0) {
   11976                     sb.append("\n");
   11977 
   11978                     // Merge several logcat streams, and take the last N lines
   11979                     InputStreamReader input = null;
   11980                     try {
   11981                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   11982                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   11983                                 "-b", "crash",
   11984                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   11985 
   11986                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   11987                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   11988                         input = new InputStreamReader(logcat.getInputStream());
   11989 
   11990                         int num;
   11991                         char[] buf = new char[8192];
   11992                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   11993                     } catch (IOException e) {
   11994                         Slog.e(TAG, "Error running logcat", e);
   11995                     } finally {
   11996                         if (input != null) try { input.close(); } catch (IOException e) {}
   11997                     }
   11998                 }
   11999 
   12000                 dbox.addText(dropboxTag, sb.toString());
   12001             }
   12002         };
   12003 
   12004         if (process == null) {
   12005             // If process is null, we are being called from some internal code
   12006             // and may be about to die -- run this synchronously.
   12007             worker.run();
   12008         } else {
   12009             worker.start();
   12010         }
   12011     }
   12012 
   12013     /**
   12014      * Bring up the "unexpected error" dialog box for a crashing app.
   12015      * Deal with edge cases (intercepts from instrumented applications,
   12016      * ActivityController, error intent receivers, that sort of thing).
   12017      * @param r the application crashing
   12018      * @param crashInfo describing the failure
   12019      */
   12020     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   12021         long timeMillis = System.currentTimeMillis();
   12022         String shortMsg = crashInfo.exceptionClassName;
   12023         String longMsg = crashInfo.exceptionMessage;
   12024         String stackTrace = crashInfo.stackTrace;
   12025         if (shortMsg != null && longMsg != null) {
   12026             longMsg = shortMsg + ": " + longMsg;
   12027         } else if (shortMsg != null) {
   12028             longMsg = shortMsg;
   12029         }
   12030 
   12031         AppErrorResult result = new AppErrorResult();
   12032         synchronized (this) {
   12033             if (mController != null) {
   12034                 try {
   12035                     String name = r != null ? r.processName : null;
   12036                     int pid = r != null ? r.pid : Binder.getCallingPid();
   12037                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
   12038                     if (!mController.appCrashed(name, pid,
   12039                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   12040                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
   12041                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
   12042                             Slog.w(TAG, "Skip killing native crashed app " + name
   12043                                     + "(" + pid + ") during testing");
   12044                         } else {
   12045                             Slog.w(TAG, "Force-killing crashed app " + name
   12046                                     + " at watcher's request");
   12047                             if (r != null) {
   12048                                 r.kill("crash", true);
   12049                             } else {
   12050                                 // Huh.
   12051                                 Process.killProcess(pid);
   12052                                 Process.killProcessGroup(uid, pid);
   12053                             }
   12054                         }
   12055                         return;
   12056                     }
   12057                 } catch (RemoteException e) {
   12058                     mController = null;
   12059                     Watchdog.getInstance().setActivityController(null);
   12060                 }
   12061             }
   12062 
   12063             final long origId = Binder.clearCallingIdentity();
   12064 
   12065             // If this process is running instrumentation, finish it.
   12066             if (r != null && r.instrumentationClass != null) {
   12067                 Slog.w(TAG, "Error in app " + r.processName
   12068                       + " running instrumentation " + r.instrumentationClass + ":");
   12069                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   12070                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   12071                 Bundle info = new Bundle();
   12072                 info.putString("shortMsg", shortMsg);
   12073                 info.putString("longMsg", longMsg);
   12074                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   12075                 Binder.restoreCallingIdentity(origId);
   12076                 return;
   12077             }
   12078 
   12079             // Log crash in battery stats.
   12080             if (r != null) {
   12081                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
   12082             }
   12083 
   12084             // If we can't identify the process or it's already exceeded its crash quota,
   12085             // quit right away without showing a crash dialog.
   12086             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   12087                 Binder.restoreCallingIdentity(origId);
   12088                 return;
   12089             }
   12090 
   12091             Message msg = Message.obtain();
   12092             msg.what = SHOW_ERROR_MSG;
   12093             HashMap data = new HashMap();
   12094             data.put("result", result);
   12095             data.put("app", r);
   12096             msg.obj = data;
   12097             mHandler.sendMessage(msg);
   12098 
   12099             Binder.restoreCallingIdentity(origId);
   12100         }
   12101 
   12102         int res = result.get();
   12103 
   12104         Intent appErrorIntent = null;
   12105         synchronized (this) {
   12106             if (r != null && !r.isolated) {
   12107                 // XXX Can't keep track of crash time for isolated processes,
   12108                 // since they don't have a persistent identity.
   12109                 mProcessCrashTimes.put(r.info.processName, r.uid,
   12110                         SystemClock.uptimeMillis());
   12111             }
   12112             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   12113                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   12114             }
   12115         }
   12116 
   12117         if (appErrorIntent != null) {
   12118             try {
   12119                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   12120             } catch (ActivityNotFoundException e) {
   12121                 Slog.w(TAG, "bug report receiver dissappeared", e);
   12122             }
   12123         }
   12124     }
   12125 
   12126     Intent createAppErrorIntentLocked(ProcessRecord r,
   12127             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12128         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   12129         if (report == null) {
   12130             return null;
   12131         }
   12132         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   12133         result.setComponent(r.errorReportReceiver);
   12134         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   12135         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   12136         return result;
   12137     }
   12138 
   12139     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   12140             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12141         if (r.errorReportReceiver == null) {
   12142             return null;
   12143         }
   12144 
   12145         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   12146             return null;
   12147         }
   12148 
   12149         ApplicationErrorReport report = new ApplicationErrorReport();
   12150         report.packageName = r.info.packageName;
   12151         report.installerPackageName = r.errorReportReceiver.getPackageName();
   12152         report.processName = r.processName;
   12153         report.time = timeMillis;
   12154         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   12155 
   12156         if (r.crashing || r.forceCrashReport) {
   12157             report.type = ApplicationErrorReport.TYPE_CRASH;
   12158             report.crashInfo = crashInfo;
   12159         } else if (r.notResponding) {
   12160             report.type = ApplicationErrorReport.TYPE_ANR;
   12161             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   12162 
   12163             report.anrInfo.activity = r.notRespondingReport.tag;
   12164             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   12165             report.anrInfo.info = r.notRespondingReport.longMsg;
   12166         }
   12167 
   12168         return report;
   12169     }
   12170 
   12171     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   12172         enforceNotIsolatedCaller("getProcessesInErrorState");
   12173         // assume our apps are happy - lazy create the list
   12174         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   12175 
   12176         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12177                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   12178         int userId = UserHandle.getUserId(Binder.getCallingUid());
   12179 
   12180         synchronized (this) {
   12181 
   12182             // iterate across all processes
   12183             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12184                 ProcessRecord app = mLruProcesses.get(i);
   12185                 if (!allUsers && app.userId != userId) {
   12186                     continue;
   12187                 }
   12188                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   12189                     // This one's in trouble, so we'll generate a report for it
   12190                     // crashes are higher priority (in case there's a crash *and* an anr)
   12191                     ActivityManager.ProcessErrorStateInfo report = null;
   12192                     if (app.crashing) {
   12193                         report = app.crashingReport;
   12194                     } else if (app.notResponding) {
   12195                         report = app.notRespondingReport;
   12196                     }
   12197 
   12198                     if (report != null) {
   12199                         if (errList == null) {
   12200                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   12201                         }
   12202                         errList.add(report);
   12203                     } else {
   12204                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   12205                                 " crashing = " + app.crashing +
   12206                                 " notResponding = " + app.notResponding);
   12207                     }
   12208                 }
   12209             }
   12210         }
   12211 
   12212         return errList;
   12213     }
   12214 
   12215     static int procStateToImportance(int procState, int memAdj,
   12216             ActivityManager.RunningAppProcessInfo currApp) {
   12217         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   12218         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   12219             currApp.lru = memAdj;
   12220         } else {
   12221             currApp.lru = 0;
   12222         }
   12223         return imp;
   12224     }
   12225 
   12226     private void fillInProcMemInfo(ProcessRecord app,
   12227             ActivityManager.RunningAppProcessInfo outInfo) {
   12228         outInfo.pid = app.pid;
   12229         outInfo.uid = app.info.uid;
   12230         if (mHeavyWeightProcess == app) {
   12231             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   12232         }
   12233         if (app.persistent) {
   12234             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   12235         }
   12236         if (app.activities.size() > 0) {
   12237             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   12238         }
   12239         outInfo.lastTrimLevel = app.trimMemoryLevel;
   12240         int adj = app.curAdj;
   12241         int procState = app.curProcState;
   12242         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   12243         outInfo.importanceReasonCode = app.adjTypeCode;
   12244         outInfo.processState = app.curProcState;
   12245     }
   12246 
   12247     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   12248         enforceNotIsolatedCaller("getRunningAppProcesses");
   12249 
   12250         final int callingUid = Binder.getCallingUid();
   12251 
   12252         // Lazy instantiation of list
   12253         List<ActivityManager.RunningAppProcessInfo> runList = null;
   12254         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12255                 callingUid) == PackageManager.PERMISSION_GRANTED;
   12256         final int userId = UserHandle.getUserId(callingUid);
   12257         final boolean allUids = isGetTasksAllowed(
   12258                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
   12259 
   12260         synchronized (this) {
   12261             // Iterate across all processes
   12262             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   12263                 ProcessRecord app = mLruProcesses.get(i);
   12264                 if ((!allUsers && app.userId != userId)
   12265                         || (!allUids && app.uid != callingUid)) {
   12266                     continue;
   12267                 }
   12268                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   12269                     // Generate process state info for running application
   12270                     ActivityManager.RunningAppProcessInfo currApp =
   12271                         new ActivityManager.RunningAppProcessInfo(app.processName,
   12272                                 app.pid, app.getPackageList());
   12273                     fillInProcMemInfo(app, currApp);
   12274                     if (app.adjSource instanceof ProcessRecord) {
   12275                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   12276                         currApp.importanceReasonImportance =
   12277                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   12278                                         app.adjSourceProcState);
   12279                     } else if (app.adjSource instanceof ActivityRecord) {
   12280                         ActivityRecord r = (ActivityRecord)app.adjSource;
   12281                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   12282                     }
   12283                     if (app.adjTarget instanceof ComponentName) {
   12284                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   12285                     }
   12286                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   12287                     //        + " lru=" + currApp.lru);
   12288                     if (runList == null) {
   12289                         runList = new ArrayList<>();
   12290                     }
   12291                     runList.add(currApp);
   12292                 }
   12293             }
   12294         }
   12295         return runList;
   12296     }
   12297 
   12298     public List<ApplicationInfo> getRunningExternalApplications() {
   12299         enforceNotIsolatedCaller("getRunningExternalApplications");
   12300         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   12301         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   12302         if (runningApps != null && runningApps.size() > 0) {
   12303             Set<String> extList = new HashSet<String>();
   12304             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   12305                 if (app.pkgList != null) {
   12306                     for (String pkg : app.pkgList) {
   12307                         extList.add(pkg);
   12308                     }
   12309                 }
   12310             }
   12311             IPackageManager pm = AppGlobals.getPackageManager();
   12312             for (String pkg : extList) {
   12313                 try {
   12314                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   12315                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   12316                         retList.add(info);
   12317                     }
   12318                 } catch (RemoteException e) {
   12319                 }
   12320             }
   12321         }
   12322         return retList;
   12323     }
   12324 
   12325     @Override
   12326     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   12327         enforceNotIsolatedCaller("getMyMemoryState");
   12328         synchronized (this) {
   12329             ProcessRecord proc;
   12330             synchronized (mPidsSelfLocked) {
   12331                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   12332             }
   12333             fillInProcMemInfo(proc, outInfo);
   12334         }
   12335     }
   12336 
   12337     @Override
   12338     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   12339         if (checkCallingPermission(android.Manifest.permission.DUMP)
   12340                 != PackageManager.PERMISSION_GRANTED) {
   12341             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   12342                     + Binder.getCallingPid()
   12343                     + ", uid=" + Binder.getCallingUid()
   12344                     + " without permission "
   12345                     + android.Manifest.permission.DUMP);
   12346             return;
   12347         }
   12348 
   12349         boolean dumpAll = false;
   12350         boolean dumpClient = false;
   12351         String dumpPackage = null;
   12352 
   12353         int opti = 0;
   12354         while (opti < args.length) {
   12355             String opt = args[opti];
   12356             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   12357                 break;
   12358             }
   12359             opti++;
   12360             if ("-a".equals(opt)) {
   12361                 dumpAll = true;
   12362             } else if ("-c".equals(opt)) {
   12363                 dumpClient = true;
   12364             } else if ("-p".equals(opt)) {
   12365                 if (opti < args.length) {
   12366                     dumpPackage = args[opti];
   12367                     opti++;
   12368                 } else {
   12369                     pw.println("Error: -p option requires package argument");
   12370                     return;
   12371                 }
   12372                 dumpClient = true;
   12373             } else if ("-h".equals(opt)) {
   12374                 pw.println("Activity manager dump options:");
   12375                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
   12376                 pw.println("  cmd may be one of:");
   12377                 pw.println("    a[ctivities]: activity stack state");
   12378                 pw.println("    r[recents]: recent activities state");
   12379                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   12380                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   12381                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   12382                 pw.println("    o[om]: out of memory management");
   12383                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   12384                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   12385                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   12386                 pw.println("    as[sociations]: tracked app associations");
   12387                 pw.println("    service [COMP_SPEC]: service client-side state");
   12388                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   12389                 pw.println("    all: dump all activities");
   12390                 pw.println("    top: dump the top activity");
   12391                 pw.println("    write: write all pending state to storage");
   12392                 pw.println("    track-associations: enable association tracking");
   12393                 pw.println("    untrack-associations: disable and clear association tracking");
   12394                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   12395                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   12396                 pw.println("    a partial substring in a component name, a");
   12397                 pw.println("    hex object identifier.");
   12398                 pw.println("  -a: include all available server state.");
   12399                 pw.println("  -c: include client state.");
   12400                 pw.println("  -p: limit output to given package.");
   12401                 return;
   12402             } else {
   12403                 pw.println("Unknown argument: " + opt + "; use -h for help");
   12404             }
   12405         }
   12406 
   12407         long origId = Binder.clearCallingIdentity();
   12408         boolean more = false;
   12409         // Is the caller requesting to dump a particular piece of data?
   12410         if (opti < args.length) {
   12411             String cmd = args[opti];
   12412             opti++;
   12413             if ("activities".equals(cmd) || "a".equals(cmd)) {
   12414                 synchronized (this) {
   12415                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12416                 }
   12417             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   12418                 synchronized (this) {
   12419                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   12420                 }
   12421             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   12422                 String[] newArgs;
   12423                 String name;
   12424                 if (opti >= args.length) {
   12425                     name = null;
   12426                     newArgs = EMPTY_STRING_ARRAY;
   12427                 } else {
   12428                     dumpPackage = args[opti];
   12429                     opti++;
   12430                     newArgs = new String[args.length - opti];
   12431                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12432                             args.length - opti);
   12433                 }
   12434                 synchronized (this) {
   12435                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   12436                 }
   12437             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   12438                 String[] newArgs;
   12439                 String name;
   12440                 if (opti >= args.length) {
   12441                     name = null;
   12442                     newArgs = EMPTY_STRING_ARRAY;
   12443                 } else {
   12444                     dumpPackage = args[opti];
   12445                     opti++;
   12446                     newArgs = new String[args.length - opti];
   12447                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12448                             args.length - opti);
   12449                 }
   12450                 synchronized (this) {
   12451                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   12452                 }
   12453             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   12454                 String[] newArgs;
   12455                 String name;
   12456                 if (opti >= args.length) {
   12457                     name = null;
   12458                     newArgs = EMPTY_STRING_ARRAY;
   12459                 } else {
   12460                     dumpPackage = args[opti];
   12461                     opti++;
   12462                     newArgs = new String[args.length - opti];
   12463                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12464                             args.length - opti);
   12465                 }
   12466                 synchronized (this) {
   12467                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   12468                 }
   12469             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   12470                 synchronized (this) {
   12471                     dumpOomLocked(fd, pw, args, opti, true);
   12472                 }
   12473             } else if ("provider".equals(cmd)) {
   12474                 String[] newArgs;
   12475                 String name;
   12476                 if (opti >= args.length) {
   12477                     name = null;
   12478                     newArgs = EMPTY_STRING_ARRAY;
   12479                 } else {
   12480                     name = args[opti];
   12481                     opti++;
   12482                     newArgs = new String[args.length - opti];
   12483                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   12484                 }
   12485                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   12486                     pw.println("No providers match: " + name);
   12487                     pw.println("Use -h for help.");
   12488                 }
   12489             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   12490                 synchronized (this) {
   12491                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   12492                 }
   12493             } else if ("service".equals(cmd)) {
   12494                 String[] newArgs;
   12495                 String name;
   12496                 if (opti >= args.length) {
   12497                     name = null;
   12498                     newArgs = EMPTY_STRING_ARRAY;
   12499                 } else {
   12500                     name = args[opti];
   12501                     opti++;
   12502                     newArgs = new String[args.length - opti];
   12503                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12504                             args.length - opti);
   12505                 }
   12506                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   12507                     pw.println("No services match: " + name);
   12508                     pw.println("Use -h for help.");
   12509                 }
   12510             } else if ("package".equals(cmd)) {
   12511                 String[] newArgs;
   12512                 if (opti >= args.length) {
   12513                     pw.println("package: no package name specified");
   12514                     pw.println("Use -h for help.");
   12515                 } else {
   12516                     dumpPackage = args[opti];
   12517                     opti++;
   12518                     newArgs = new String[args.length - opti];
   12519                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12520                             args.length - opti);
   12521                     args = newArgs;
   12522                     opti = 0;
   12523                     more = true;
   12524                 }
   12525             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   12526                 synchronized (this) {
   12527                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12528                 }
   12529             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   12530                 synchronized (this) {
   12531                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12532                 }
   12533             } else if ("write".equals(cmd)) {
   12534                 mTaskPersister.flush();
   12535                 pw.println("All tasks persisted.");
   12536                 return;
   12537             } else if ("track-associations".equals(cmd)) {
   12538                 synchronized (this) {
   12539                     if (!mTrackingAssociations) {
   12540                         mTrackingAssociations = true;
   12541                         pw.println("Association tracking started.");
   12542                     } else {
   12543                         pw.println("Association tracking already enabled.");
   12544                     }
   12545                 }
   12546                 return;
   12547             } else if ("untrack-associations".equals(cmd)) {
   12548                 synchronized (this) {
   12549                     if (mTrackingAssociations) {
   12550                         mTrackingAssociations = false;
   12551                         mAssociations.clear();
   12552                         pw.println("Association tracking stopped.");
   12553                     } else {
   12554                         pw.println("Association tracking not running.");
   12555                     }
   12556                 }
   12557                 return;
   12558             } else {
   12559                 // Dumping a single activity?
   12560                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   12561                     pw.println("Bad activity command, or no activities match: " + cmd);
   12562                     pw.println("Use -h for help.");
   12563                 }
   12564             }
   12565             if (!more) {
   12566                 Binder.restoreCallingIdentity(origId);
   12567                 return;
   12568             }
   12569         }
   12570 
   12571         // No piece of data specified, dump everything.
   12572         synchronized (this) {
   12573             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12574             pw.println();
   12575             if (dumpAll) {
   12576                 pw.println("-------------------------------------------------------------------------------");
   12577             }
   12578             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12579             pw.println();
   12580             if (dumpAll) {
   12581                 pw.println("-------------------------------------------------------------------------------");
   12582             }
   12583             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12584             pw.println();
   12585             if (dumpAll) {
   12586                 pw.println("-------------------------------------------------------------------------------");
   12587             }
   12588             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12589             pw.println();
   12590             if (dumpAll) {
   12591                 pw.println("-------------------------------------------------------------------------------");
   12592             }
   12593             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12594             pw.println();
   12595             if (dumpAll) {
   12596                 pw.println("-------------------------------------------------------------------------------");
   12597             }
   12598             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12599             if (mAssociations.size() > 0) {
   12600                 pw.println();
   12601                 if (dumpAll) {
   12602                     pw.println("-------------------------------------------------------------------------------");
   12603                 }
   12604                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12605             }
   12606             pw.println();
   12607             if (dumpAll) {
   12608                 pw.println("-------------------------------------------------------------------------------");
   12609             }
   12610             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12611         }
   12612         Binder.restoreCallingIdentity(origId);
   12613     }
   12614 
   12615     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12616             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   12617         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   12618 
   12619         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   12620                 dumpPackage);
   12621         boolean needSep = printedAnything;
   12622 
   12623         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   12624                 dumpPackage, needSep, "  mFocusedActivity: ");
   12625         if (printed) {
   12626             printedAnything = true;
   12627             needSep = false;
   12628         }
   12629 
   12630         if (dumpPackage == null) {
   12631             if (needSep) {
   12632                 pw.println();
   12633             }
   12634             needSep = true;
   12635             printedAnything = true;
   12636             mStackSupervisor.dump(pw, "  ");
   12637         }
   12638 
   12639         if (!printedAnything) {
   12640             pw.println("  (nothing)");
   12641         }
   12642     }
   12643 
   12644     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12645             int opti, boolean dumpAll, String dumpPackage) {
   12646         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   12647 
   12648         boolean printedAnything = false;
   12649 
   12650         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   12651             boolean printedHeader = false;
   12652 
   12653             final int N = mRecentTasks.size();
   12654             for (int i=0; i<N; i++) {
   12655                 TaskRecord tr = mRecentTasks.get(i);
   12656                 if (dumpPackage != null) {
   12657                     if (tr.realActivity == null ||
   12658                             !dumpPackage.equals(tr.realActivity)) {
   12659                         continue;
   12660                     }
   12661                 }
   12662                 if (!printedHeader) {
   12663                     pw.println("  Recent tasks:");
   12664                     printedHeader = true;
   12665                     printedAnything = true;
   12666                 }
   12667                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   12668                         pw.println(tr);
   12669                 if (dumpAll) {
   12670                     mRecentTasks.get(i).dump(pw, "    ");
   12671                 }
   12672             }
   12673         }
   12674 
   12675         if (!printedAnything) {
   12676             pw.println("  (nothing)");
   12677         }
   12678     }
   12679 
   12680     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12681             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   12682         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   12683 
   12684         int dumpUid = 0;
   12685         if (dumpPackage != null) {
   12686             IPackageManager pm = AppGlobals.getPackageManager();
   12687             try {
   12688                 dumpUid = pm.getPackageUid(dumpPackage, 0);
   12689             } catch (RemoteException e) {
   12690             }
   12691         }
   12692 
   12693         boolean printedAnything = false;
   12694 
   12695         final long now = SystemClock.uptimeMillis();
   12696 
   12697         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   12698             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   12699                     = mAssociations.valueAt(i1);
   12700             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   12701                 SparseArray<ArrayMap<String, Association>> sourceUids
   12702                         = targetComponents.valueAt(i2);
   12703                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   12704                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   12705                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   12706                         Association ass = sourceProcesses.valueAt(i4);
   12707                         if (dumpPackage != null) {
   12708                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   12709                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   12710                                 continue;
   12711                             }
   12712                         }
   12713                         printedAnything = true;
   12714                         pw.print("  ");
   12715                         pw.print(ass.mTargetProcess);
   12716                         pw.print("/");
   12717                         UserHandle.formatUid(pw, ass.mTargetUid);
   12718                         pw.print(" <- ");
   12719                         pw.print(ass.mSourceProcess);
   12720                         pw.print("/");
   12721                         UserHandle.formatUid(pw, ass.mSourceUid);
   12722                         pw.println();
   12723                         pw.print("    via ");
   12724                         pw.print(ass.mTargetComponent.flattenToShortString());
   12725                         pw.println();
   12726                         pw.print("    ");
   12727                         long dur = ass.mTime;
   12728                         if (ass.mNesting > 0) {
   12729                             dur += now - ass.mStartTime;
   12730                         }
   12731                         TimeUtils.formatDuration(dur, pw);
   12732                         pw.print(" (");
   12733                         pw.print(ass.mCount);
   12734                         pw.println(" times)");
   12735                         if (ass.mNesting > 0) {
   12736                             pw.print("    ");
   12737                             pw.print(" Currently active: ");
   12738                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   12739                             pw.println();
   12740                         }
   12741                     }
   12742                 }
   12743             }
   12744 
   12745         }
   12746 
   12747         if (!printedAnything) {
   12748             pw.println("  (nothing)");
   12749         }
   12750     }
   12751 
   12752     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12753             int opti, boolean dumpAll, String dumpPackage) {
   12754         boolean needSep = false;
   12755         boolean printedAnything = false;
   12756         int numPers = 0;
   12757 
   12758         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   12759 
   12760         if (dumpAll) {
   12761             final int NP = mProcessNames.getMap().size();
   12762             for (int ip=0; ip<NP; ip++) {
   12763                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   12764                 final int NA = procs.size();
   12765                 for (int ia=0; ia<NA; ia++) {
   12766                     ProcessRecord r = procs.valueAt(ia);
   12767                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12768                         continue;
   12769                     }
   12770                     if (!needSep) {
   12771                         pw.println("  All known processes:");
   12772                         needSep = true;
   12773                         printedAnything = true;
   12774                     }
   12775                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   12776                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   12777                         pw.print(" "); pw.println(r);
   12778                     r.dump(pw, "    ");
   12779                     if (r.persistent) {
   12780                         numPers++;
   12781                     }
   12782                 }
   12783             }
   12784         }
   12785 
   12786         if (mIsolatedProcesses.size() > 0) {
   12787             boolean printed = false;
   12788             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   12789                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   12790                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12791                     continue;
   12792                 }
   12793                 if (!printed) {
   12794                     if (needSep) {
   12795                         pw.println();
   12796                     }
   12797                     pw.println("  Isolated process list (sorted by uid):");
   12798                     printedAnything = true;
   12799                     printed = true;
   12800                     needSep = true;
   12801                 }
   12802                 pw.println(String.format("%sIsolated #%2d: %s",
   12803                         "    ", i, r.toString()));
   12804             }
   12805         }
   12806 
   12807         if (mLruProcesses.size() > 0) {
   12808             if (needSep) {
   12809                 pw.println();
   12810             }
   12811             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   12812                     pw.print(" total, non-act at ");
   12813                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   12814                     pw.print(", non-svc at ");
   12815                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   12816                     pw.println("):");
   12817             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   12818             needSep = true;
   12819             printedAnything = true;
   12820         }
   12821 
   12822         if (dumpAll || dumpPackage != null) {
   12823             synchronized (mPidsSelfLocked) {
   12824                 boolean printed = false;
   12825                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   12826                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   12827                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12828                         continue;
   12829                     }
   12830                     if (!printed) {
   12831                         if (needSep) pw.println();
   12832                         needSep = true;
   12833                         pw.println("  PID mappings:");
   12834                         printed = true;
   12835                         printedAnything = true;
   12836                     }
   12837                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   12838                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   12839                 }
   12840             }
   12841         }
   12842 
   12843         if (mForegroundProcesses.size() > 0) {
   12844             synchronized (mPidsSelfLocked) {
   12845                 boolean printed = false;
   12846                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   12847                     ProcessRecord r = mPidsSelfLocked.get(
   12848                             mForegroundProcesses.valueAt(i).pid);
   12849                     if (dumpPackage != null && (r == null
   12850                             || !r.pkgList.containsKey(dumpPackage))) {
   12851                         continue;
   12852                     }
   12853                     if (!printed) {
   12854                         if (needSep) pw.println();
   12855                         needSep = true;
   12856                         pw.println("  Foreground Processes:");
   12857                         printed = true;
   12858                         printedAnything = true;
   12859                     }
   12860                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   12861                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   12862                 }
   12863             }
   12864         }
   12865 
   12866         if (mPersistentStartingProcesses.size() > 0) {
   12867             if (needSep) pw.println();
   12868             needSep = true;
   12869             printedAnything = true;
   12870             pw.println("  Persisent processes that are starting:");
   12871             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   12872                     "Starting Norm", "Restarting PERS", dumpPackage);
   12873         }
   12874 
   12875         if (mRemovedProcesses.size() > 0) {
   12876             if (needSep) pw.println();
   12877             needSep = true;
   12878             printedAnything = true;
   12879             pw.println("  Processes that are being removed:");
   12880             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   12881                     "Removed Norm", "Removed PERS", dumpPackage);
   12882         }
   12883 
   12884         if (mProcessesOnHold.size() > 0) {
   12885             if (needSep) pw.println();
   12886             needSep = true;
   12887             printedAnything = true;
   12888             pw.println("  Processes that are on old until the system is ready:");
   12889             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   12890                     "OnHold Norm", "OnHold PERS", dumpPackage);
   12891         }
   12892 
   12893         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   12894 
   12895         if (mProcessCrashTimes.getMap().size() > 0) {
   12896             boolean printed = false;
   12897             long now = SystemClock.uptimeMillis();
   12898             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   12899             final int NP = pmap.size();
   12900             for (int ip=0; ip<NP; ip++) {
   12901                 String pname = pmap.keyAt(ip);
   12902                 SparseArray<Long> uids = pmap.valueAt(ip);
   12903                 final int N = uids.size();
   12904                 for (int i=0; i<N; i++) {
   12905                     int puid = uids.keyAt(i);
   12906                     ProcessRecord r = mProcessNames.get(pname, puid);
   12907                     if (dumpPackage != null && (r == null
   12908                             || !r.pkgList.containsKey(dumpPackage))) {
   12909                         continue;
   12910                     }
   12911                     if (!printed) {
   12912                         if (needSep) pw.println();
   12913                         needSep = true;
   12914                         pw.println("  Time since processes crashed:");
   12915                         printed = true;
   12916                         printedAnything = true;
   12917                     }
   12918                     pw.print("    Process "); pw.print(pname);
   12919                             pw.print(" uid "); pw.print(puid);
   12920                             pw.print(": last crashed ");
   12921                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   12922                             pw.println(" ago");
   12923                 }
   12924             }
   12925         }
   12926 
   12927         if (mBadProcesses.getMap().size() > 0) {
   12928             boolean printed = false;
   12929             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
   12930             final int NP = pmap.size();
   12931             for (int ip=0; ip<NP; ip++) {
   12932                 String pname = pmap.keyAt(ip);
   12933                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
   12934                 final int N = uids.size();
   12935                 for (int i=0; i<N; i++) {
   12936                     int puid = uids.keyAt(i);
   12937                     ProcessRecord r = mProcessNames.get(pname, puid);
   12938                     if (dumpPackage != null && (r == null
   12939                             || !r.pkgList.containsKey(dumpPackage))) {
   12940                         continue;
   12941                     }
   12942                     if (!printed) {
   12943                         if (needSep) pw.println();
   12944                         needSep = true;
   12945                         pw.println("  Bad processes:");
   12946                         printedAnything = true;
   12947                     }
   12948                     BadProcessInfo info = uids.valueAt(i);
   12949                     pw.print("    Bad process "); pw.print(pname);
   12950                             pw.print(" uid "); pw.print(puid);
   12951                             pw.print(": crashed at time "); pw.println(info.time);
   12952                     if (info.shortMsg != null) {
   12953                         pw.print("      Short msg: "); pw.println(info.shortMsg);
   12954                     }
   12955                     if (info.longMsg != null) {
   12956                         pw.print("      Long msg: "); pw.println(info.longMsg);
   12957                     }
   12958                     if (info.stack != null) {
   12959                         pw.println("      Stack:");
   12960                         int lastPos = 0;
   12961                         for (int pos=0; pos<info.stack.length(); pos++) {
   12962                             if (info.stack.charAt(pos) == '\n') {
   12963                                 pw.print("        ");
   12964                                 pw.write(info.stack, lastPos, pos-lastPos);
   12965                                 pw.println();
   12966                                 lastPos = pos+1;
   12967                             }
   12968                         }
   12969                         if (lastPos < info.stack.length()) {
   12970                             pw.print("        ");
   12971                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
   12972                             pw.println();
   12973                         }
   12974                     }
   12975                 }
   12976             }
   12977         }
   12978 
   12979         if (dumpPackage == null) {
   12980             pw.println();
   12981             needSep = false;
   12982             pw.println("  mStartedUsers:");
   12983             for (int i=0; i<mStartedUsers.size(); i++) {
   12984                 UserStartedState uss = mStartedUsers.valueAt(i);
   12985                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   12986                         pw.print(": "); uss.dump("", pw);
   12987             }
   12988             pw.print("  mStartedUserArray: [");
   12989             for (int i=0; i<mStartedUserArray.length; i++) {
   12990                 if (i > 0) pw.print(", ");
   12991                 pw.print(mStartedUserArray[i]);
   12992             }
   12993             pw.println("]");
   12994             pw.print("  mUserLru: [");
   12995             for (int i=0; i<mUserLru.size(); i++) {
   12996                 if (i > 0) pw.print(", ");
   12997                 pw.print(mUserLru.get(i));
   12998             }
   12999             pw.println("]");
   13000             if (dumpAll) {
   13001                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   13002             }
   13003             synchronized (mUserProfileGroupIdsSelfLocked) {
   13004                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
   13005                     pw.println("  mUserProfileGroupIds:");
   13006                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
   13007                         pw.print("    User #");
   13008                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
   13009                         pw.print(" -> profile #");
   13010                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
   13011                     }
   13012                 }
   13013             }
   13014         }
   13015         if (mHomeProcess != null && (dumpPackage == null
   13016                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   13017             if (needSep) {
   13018                 pw.println();
   13019                 needSep = false;
   13020             }
   13021             pw.println("  mHomeProcess: " + mHomeProcess);
   13022         }
   13023         if (mPreviousProcess != null && (dumpPackage == null
   13024                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   13025             if (needSep) {
   13026                 pw.println();
   13027                 needSep = false;
   13028             }
   13029             pw.println("  mPreviousProcess: " + mPreviousProcess);
   13030         }
   13031         if (dumpAll) {
   13032             StringBuilder sb = new StringBuilder(128);
   13033             sb.append("  mPreviousProcessVisibleTime: ");
   13034             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   13035             pw.println(sb);
   13036         }
   13037         if (mHeavyWeightProcess != null && (dumpPackage == null
   13038                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   13039             if (needSep) {
   13040                 pw.println();
   13041                 needSep = false;
   13042             }
   13043             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   13044         }
   13045         if (dumpPackage == null) {
   13046             pw.println("  mConfiguration: " + mConfiguration);
   13047         }
   13048         if (dumpAll) {
   13049             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   13050             if (mCompatModePackages.getPackages().size() > 0) {
   13051                 boolean printed = false;
   13052                 for (Map.Entry<String, Integer> entry
   13053                         : mCompatModePackages.getPackages().entrySet()) {
   13054                     String pkg = entry.getKey();
   13055                     int mode = entry.getValue();
   13056                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   13057                         continue;
   13058                     }
   13059                     if (!printed) {
   13060                         pw.println("  mScreenCompatPackages:");
   13061                         printed = true;
   13062                     }
   13063                     pw.print("    "); pw.print(pkg); pw.print(": ");
   13064                             pw.print(mode); pw.println();
   13065                 }
   13066             }
   13067         }
   13068         if (dumpPackage == null) {
   13069             pw.println("  mWakefulness="
   13070                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   13071             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
   13072                     + lockScreenShownToString());
   13073             pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
   13074                     + " mTestPssMode=" + mTestPssMode);
   13075         }
   13076         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   13077                 || mOrigWaitForDebugger) {
   13078             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   13079                     || dumpPackage.equals(mOrigDebugApp)) {
   13080                 if (needSep) {
   13081                     pw.println();
   13082                     needSep = false;
   13083                 }
   13084                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   13085                         + " mDebugTransient=" + mDebugTransient
   13086                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   13087             }
   13088         }
   13089         if (mOpenGlTraceApp != null) {
   13090             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   13091                 if (needSep) {
   13092                     pw.println();
   13093                     needSep = false;
   13094                 }
   13095                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   13096             }
   13097         }
   13098         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   13099                 || mProfileFd != null) {
   13100             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   13101                 if (needSep) {
   13102                     pw.println();
   13103                     needSep = false;
   13104                 }
   13105                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   13106                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   13107                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   13108                         + mAutoStopProfiler);
   13109                 pw.println("  mProfileType=" + mProfileType);
   13110             }
   13111         }
   13112         if (dumpPackage == null) {
   13113             if (mAlwaysFinishActivities || mController != null) {
   13114                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   13115                         + " mController=" + mController);
   13116             }
   13117             if (dumpAll) {
   13118                 pw.println("  Total persistent processes: " + numPers);
   13119                 pw.println("  mProcessesReady=" + mProcessesReady
   13120                         + " mSystemReady=" + mSystemReady
   13121                         + " mBooted=" + mBooted
   13122                         + " mFactoryTest=" + mFactoryTest);
   13123                 pw.println("  mBooting=" + mBooting
   13124                         + " mCallFinishBooting=" + mCallFinishBooting
   13125                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   13126                 pw.print("  mLastPowerCheckRealtime=");
   13127                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   13128                         pw.println("");
   13129                 pw.print("  mLastPowerCheckUptime=");
   13130                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   13131                         pw.println("");
   13132                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   13133                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   13134                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   13135                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   13136                         + " (" + mLruProcesses.size() + " total)"
   13137                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   13138                         + " mNumServiceProcs=" + mNumServiceProcs
   13139                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   13140                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   13141                         + " mLastMemoryLevel" + mLastMemoryLevel
   13142                         + " mLastNumProcesses" + mLastNumProcesses);
   13143                 long now = SystemClock.uptimeMillis();
   13144                 pw.print("  mLastIdleTime=");
   13145                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   13146                         pw.print(" mLowRamSinceLastIdle=");
   13147                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   13148                         pw.println();
   13149             }
   13150         }
   13151 
   13152         if (!printedAnything) {
   13153             pw.println("  (nothing)");
   13154         }
   13155     }
   13156 
   13157     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   13158             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   13159         if (mProcessesToGc.size() > 0) {
   13160             boolean printed = false;
   13161             long now = SystemClock.uptimeMillis();
   13162             for (int i=0; i<mProcessesToGc.size(); i++) {
   13163                 ProcessRecord proc = mProcessesToGc.get(i);
   13164                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   13165                     continue;
   13166                 }
   13167                 if (!printed) {
   13168                     if (needSep) pw.println();
   13169                     needSep = true;
   13170                     pw.println("  Processes that are waiting to GC:");
   13171                     printed = true;
   13172                 }
   13173                 pw.print("    Process "); pw.println(proc);
   13174                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   13175                         pw.print(", last gced=");
   13176                         pw.print(now-proc.lastRequestedGc);
   13177                         pw.print(" ms ago, last lowMem=");
   13178                         pw.print(now-proc.lastLowMemory);
   13179                         pw.println(" ms ago");
   13180 
   13181             }
   13182         }
   13183         return needSep;
   13184     }
   13185 
   13186     void printOomLevel(PrintWriter pw, String name, int adj) {
   13187         pw.print("    ");
   13188         if (adj >= 0) {
   13189             pw.print(' ');
   13190             if (adj < 10) pw.print(' ');
   13191         } else {
   13192             if (adj > -10) pw.print(' ');
   13193         }
   13194         pw.print(adj);
   13195         pw.print(": ");
   13196         pw.print(name);
   13197         pw.print(" (");
   13198         pw.print(mProcessList.getMemLevel(adj)/1024);
   13199         pw.println(" kB)");
   13200     }
   13201 
   13202     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13203             int opti, boolean dumpAll) {
   13204         boolean needSep = false;
   13205 
   13206         if (mLruProcesses.size() > 0) {
   13207             if (needSep) pw.println();
   13208             needSep = true;
   13209             pw.println("  OOM levels:");
   13210             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   13211             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   13212             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   13213             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   13214             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   13215             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   13216             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   13217             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   13218             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   13219             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   13220             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   13221             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   13222             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   13223             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   13224 
   13225             if (needSep) pw.println();
   13226             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   13227                     pw.print(" total, non-act at ");
   13228                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   13229                     pw.print(", non-svc at ");
   13230                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   13231                     pw.println("):");
   13232             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   13233             needSep = true;
   13234         }
   13235 
   13236         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   13237 
   13238         pw.println();
   13239         pw.println("  mHomeProcess: " + mHomeProcess);
   13240         pw.println("  mPreviousProcess: " + mPreviousProcess);
   13241         if (mHeavyWeightProcess != null) {
   13242             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   13243         }
   13244 
   13245         return true;
   13246     }
   13247 
   13248     /**
   13249      * There are three ways to call this:
   13250      *  - no provider specified: dump all the providers
   13251      *  - a flattened component name that matched an existing provider was specified as the
   13252      *    first arg: dump that one provider
   13253      *  - the first arg isn't the flattened component name of an existing provider:
   13254      *    dump all providers whose component contains the first arg as a substring
   13255      */
   13256     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13257             int opti, boolean dumpAll) {
   13258         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   13259     }
   13260 
   13261     static class ItemMatcher {
   13262         ArrayList<ComponentName> components;
   13263         ArrayList<String> strings;
   13264         ArrayList<Integer> objects;
   13265         boolean all;
   13266 
   13267         ItemMatcher() {
   13268             all = true;
   13269         }
   13270 
   13271         void build(String name) {
   13272             ComponentName componentName = ComponentName.unflattenFromString(name);
   13273             if (componentName != null) {
   13274                 if (components == null) {
   13275                     components = new ArrayList<ComponentName>();
   13276                 }
   13277                 components.add(componentName);
   13278                 all = false;
   13279             } else {
   13280                 int objectId = 0;
   13281                 // Not a '/' separated full component name; maybe an object ID?
   13282                 try {
   13283                     objectId = Integer.parseInt(name, 16);
   13284                     if (objects == null) {
   13285                         objects = new ArrayList<Integer>();
   13286                     }
   13287                     objects.add(objectId);
   13288                     all = false;
   13289                 } catch (RuntimeException e) {
   13290                     // Not an integer; just do string match.
   13291                     if (strings == null) {
   13292                         strings = new ArrayList<String>();
   13293                     }
   13294                     strings.add(name);
   13295                     all = false;
   13296                 }
   13297             }
   13298         }
   13299 
   13300         int build(String[] args, int opti) {
   13301             for (; opti<args.length; opti++) {
   13302                 String name = args[opti];
   13303                 if ("--".equals(name)) {
   13304                     return opti+1;
   13305                 }
   13306                 build(name);
   13307             }
   13308             return opti;
   13309         }
   13310 
   13311         boolean match(Object object, ComponentName comp) {
   13312             if (all) {
   13313                 return true;
   13314             }
   13315             if (components != null) {
   13316                 for (int i=0; i<components.size(); i++) {
   13317                     if (components.get(i).equals(comp)) {
   13318                         return true;
   13319                     }
   13320                 }
   13321             }
   13322             if (objects != null) {
   13323                 for (int i=0; i<objects.size(); i++) {
   13324                     if (System.identityHashCode(object) == objects.get(i)) {
   13325                         return true;
   13326                     }
   13327                 }
   13328             }
   13329             if (strings != null) {
   13330                 String flat = comp.flattenToString();
   13331                 for (int i=0; i<strings.size(); i++) {
   13332                     if (flat.contains(strings.get(i))) {
   13333                         return true;
   13334                     }
   13335                 }
   13336             }
   13337             return false;
   13338         }
   13339     }
   13340 
   13341     /**
   13342      * There are three things that cmd can be:
   13343      *  - a flattened component name that matches an existing activity
   13344      *  - the cmd arg isn't the flattened component name of an existing activity:
   13345      *    dump all activity whose component contains the cmd as a substring
   13346      *  - A hex number of the ActivityRecord object instance.
   13347      */
   13348     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13349             int opti, boolean dumpAll) {
   13350         ArrayList<ActivityRecord> activities;
   13351 
   13352         synchronized (this) {
   13353             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   13354         }
   13355 
   13356         if (activities.size() <= 0) {
   13357             return false;
   13358         }
   13359 
   13360         String[] newArgs = new String[args.length - opti];
   13361         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   13362 
   13363         TaskRecord lastTask = null;
   13364         boolean needSep = false;
   13365         for (int i=activities.size()-1; i>=0; i--) {
   13366             ActivityRecord r = activities.get(i);
   13367             if (needSep) {
   13368                 pw.println();
   13369             }
   13370             needSep = true;
   13371             synchronized (this) {
   13372                 if (lastTask != r.task) {
   13373                     lastTask = r.task;
   13374                     pw.print("TASK "); pw.print(lastTask.affinity);
   13375                             pw.print(" id="); pw.println(lastTask.taskId);
   13376                     if (dumpAll) {
   13377                         lastTask.dump(pw, "  ");
   13378                     }
   13379                 }
   13380             }
   13381             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   13382         }
   13383         return true;
   13384     }
   13385 
   13386     /**
   13387      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   13388      * there is a thread associated with the activity.
   13389      */
   13390     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   13391             final ActivityRecord r, String[] args, boolean dumpAll) {
   13392         String innerPrefix = prefix + "  ";
   13393         synchronized (this) {
   13394             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   13395                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   13396                     pw.print(" pid=");
   13397                     if (r.app != null) pw.println(r.app.pid);
   13398                     else pw.println("(not running)");
   13399             if (dumpAll) {
   13400                 r.dump(pw, innerPrefix);
   13401             }
   13402         }
   13403         if (r.app != null && r.app.thread != null) {
   13404             // flush anything that is already in the PrintWriter since the thread is going
   13405             // to write to the file descriptor directly
   13406             pw.flush();
   13407             try {
   13408                 TransferPipe tp = new TransferPipe();
   13409                 try {
   13410                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   13411                             r.appToken, innerPrefix, args);
   13412                     tp.go(fd);
   13413                 } finally {
   13414                     tp.kill();
   13415                 }
   13416             } catch (IOException e) {
   13417                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   13418             } catch (RemoteException e) {
   13419                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   13420             }
   13421         }
   13422     }
   13423 
   13424     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13425             int opti, boolean dumpAll, String dumpPackage) {
   13426         boolean needSep = false;
   13427         boolean onlyHistory = false;
   13428         boolean printedAnything = false;
   13429 
   13430         if ("history".equals(dumpPackage)) {
   13431             if (opti < args.length && "-s".equals(args[opti])) {
   13432                 dumpAll = false;
   13433             }
   13434             onlyHistory = true;
   13435             dumpPackage = null;
   13436         }
   13437 
   13438         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   13439         if (!onlyHistory && dumpAll) {
   13440             if (mRegisteredReceivers.size() > 0) {
   13441                 boolean printed = false;
   13442                 Iterator it = mRegisteredReceivers.values().iterator();
   13443                 while (it.hasNext()) {
   13444                     ReceiverList r = (ReceiverList)it.next();
   13445                     if (dumpPackage != null && (r.app == null ||
   13446                             !dumpPackage.equals(r.app.info.packageName))) {
   13447                         continue;
   13448                     }
   13449                     if (!printed) {
   13450                         pw.println("  Registered Receivers:");
   13451                         needSep = true;
   13452                         printed = true;
   13453                         printedAnything = true;
   13454                     }
   13455                     pw.print("  * "); pw.println(r);
   13456                     r.dump(pw, "    ");
   13457                 }
   13458             }
   13459 
   13460             if (mReceiverResolver.dump(pw, needSep ?
   13461                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   13462                     "    ", dumpPackage, false, false)) {
   13463                 needSep = true;
   13464                 printedAnything = true;
   13465             }
   13466         }
   13467 
   13468         for (BroadcastQueue q : mBroadcastQueues) {
   13469             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   13470             printedAnything |= needSep;
   13471         }
   13472 
   13473         needSep = true;
   13474 
   13475         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   13476             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   13477                 if (needSep) {
   13478                     pw.println();
   13479                 }
   13480                 needSep = true;
   13481                 printedAnything = true;
   13482                 pw.print("  Sticky broadcasts for user ");
   13483                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   13484                 StringBuilder sb = new StringBuilder(128);
   13485                 for (Map.Entry<String, ArrayList<Intent>> ent
   13486                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   13487                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   13488                     if (dumpAll) {
   13489                         pw.println(":");
   13490                         ArrayList<Intent> intents = ent.getValue();
   13491                         final int N = intents.size();
   13492                         for (int i=0; i<N; i++) {
   13493                             sb.setLength(0);
   13494                             sb.append("    Intent: ");
   13495                             intents.get(i).toShortString(sb, false, true, false, false);
   13496                             pw.println(sb.toString());
   13497                             Bundle bundle = intents.get(i).getExtras();
   13498                             if (bundle != null) {
   13499                                 pw.print("      ");
   13500                                 pw.println(bundle.toString());
   13501                             }
   13502                         }
   13503                     } else {
   13504                         pw.println("");
   13505                     }
   13506                 }
   13507             }
   13508         }
   13509 
   13510         if (!onlyHistory && dumpAll) {
   13511             pw.println();
   13512             for (BroadcastQueue queue : mBroadcastQueues) {
   13513                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   13514                         + queue.mBroadcastsScheduled);
   13515             }
   13516             pw.println("  mHandler:");
   13517             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   13518             needSep = true;
   13519             printedAnything = true;
   13520         }
   13521 
   13522         if (!printedAnything) {
   13523             pw.println("  (nothing)");
   13524         }
   13525     }
   13526 
   13527     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13528             int opti, boolean dumpAll, String dumpPackage) {
   13529         boolean needSep;
   13530         boolean printedAnything = false;
   13531 
   13532         ItemMatcher matcher = new ItemMatcher();
   13533         matcher.build(args, opti);
   13534 
   13535         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   13536 
   13537         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   13538         printedAnything |= needSep;
   13539 
   13540         if (mLaunchingProviders.size() > 0) {
   13541             boolean printed = false;
   13542             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   13543                 ContentProviderRecord r = mLaunchingProviders.get(i);
   13544                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   13545                     continue;
   13546                 }
   13547                 if (!printed) {
   13548                     if (needSep) pw.println();
   13549                     needSep = true;
   13550                     pw.println("  Launching content providers:");
   13551                     printed = true;
   13552                     printedAnything = true;
   13553                 }
   13554                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   13555                         pw.println(r);
   13556             }
   13557         }
   13558 
   13559         if (mGrantedUriPermissions.size() > 0) {
   13560             boolean printed = false;
   13561             int dumpUid = -2;
   13562             if (dumpPackage != null) {
   13563                 try {
   13564                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   13565                 } catch (NameNotFoundException e) {
   13566                     dumpUid = -1;
   13567                 }
   13568             }
   13569             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   13570                 int uid = mGrantedUriPermissions.keyAt(i);
   13571                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   13572                     continue;
   13573                 }
   13574                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   13575                 if (!printed) {
   13576                     if (needSep) pw.println();
   13577                     needSep = true;
   13578                     pw.println("  Granted Uri Permissions:");
   13579                     printed = true;
   13580                     printedAnything = true;
   13581                 }
   13582                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   13583                 for (UriPermission perm : perms.values()) {
   13584                     pw.print("    "); pw.println(perm);
   13585                     if (dumpAll) {
   13586                         perm.dump(pw, "      ");
   13587                     }
   13588                 }
   13589             }
   13590         }
   13591 
   13592         if (!printedAnything) {
   13593             pw.println("  (nothing)");
   13594         }
   13595     }
   13596 
   13597     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13598             int opti, boolean dumpAll, String dumpPackage) {
   13599         boolean printed = false;
   13600 
   13601         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   13602 
   13603         if (mIntentSenderRecords.size() > 0) {
   13604             Iterator<WeakReference<PendingIntentRecord>> it
   13605                     = mIntentSenderRecords.values().iterator();
   13606             while (it.hasNext()) {
   13607                 WeakReference<PendingIntentRecord> ref = it.next();
   13608                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   13609                 if (dumpPackage != null && (rec == null
   13610                         || !dumpPackage.equals(rec.key.packageName))) {
   13611                     continue;
   13612                 }
   13613                 printed = true;
   13614                 if (rec != null) {
   13615                     pw.print("  * "); pw.println(rec);
   13616                     if (dumpAll) {
   13617                         rec.dump(pw, "    ");
   13618                     }
   13619                 } else {
   13620                     pw.print("  * "); pw.println(ref);
   13621                 }
   13622             }
   13623         }
   13624 
   13625         if (!printed) {
   13626             pw.println("  (nothing)");
   13627         }
   13628     }
   13629 
   13630     private static final int dumpProcessList(PrintWriter pw,
   13631             ActivityManagerService service, List list,
   13632             String prefix, String normalLabel, String persistentLabel,
   13633             String dumpPackage) {
   13634         int numPers = 0;
   13635         final int N = list.size()-1;
   13636         for (int i=N; i>=0; i--) {
   13637             ProcessRecord r = (ProcessRecord)list.get(i);
   13638             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   13639                 continue;
   13640             }
   13641             pw.println(String.format("%s%s #%2d: %s",
   13642                     prefix, (r.persistent ? persistentLabel : normalLabel),
   13643                     i, r.toString()));
   13644             if (r.persistent) {
   13645                 numPers++;
   13646             }
   13647         }
   13648         return numPers;
   13649     }
   13650 
   13651     private static final boolean dumpProcessOomList(PrintWriter pw,
   13652             ActivityManagerService service, List<ProcessRecord> origList,
   13653             String prefix, String normalLabel, String persistentLabel,
   13654             boolean inclDetails, String dumpPackage) {
   13655 
   13656         ArrayList<Pair<ProcessRecord, Integer>> list
   13657                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   13658         for (int i=0; i<origList.size(); i++) {
   13659             ProcessRecord r = origList.get(i);
   13660             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   13661                 continue;
   13662             }
   13663             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   13664         }
   13665 
   13666         if (list.size() <= 0) {
   13667             return false;
   13668         }
   13669 
   13670         Comparator<Pair<ProcessRecord, Integer>> comparator
   13671                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   13672             @Override
   13673             public int compare(Pair<ProcessRecord, Integer> object1,
   13674                     Pair<ProcessRecord, Integer> object2) {
   13675                 if (object1.first.setAdj != object2.first.setAdj) {
   13676                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   13677                 }
   13678                 if (object1.second.intValue() != object2.second.intValue()) {
   13679                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   13680                 }
   13681                 return 0;
   13682             }
   13683         };
   13684 
   13685         Collections.sort(list, comparator);
   13686 
   13687         final long curRealtime = SystemClock.elapsedRealtime();
   13688         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   13689         final long curUptime = SystemClock.uptimeMillis();
   13690         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   13691 
   13692         for (int i=list.size()-1; i>=0; i--) {
   13693             ProcessRecord r = list.get(i).first;
   13694             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   13695             char schedGroup;
   13696             switch (r.setSchedGroup) {
   13697                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   13698                     schedGroup = 'B';
   13699                     break;
   13700                 case Process.THREAD_GROUP_DEFAULT:
   13701                     schedGroup = 'F';
   13702                     break;
   13703                 default:
   13704                     schedGroup = '?';
   13705                     break;
   13706             }
   13707             char foreground;
   13708             if (r.foregroundActivities) {
   13709                 foreground = 'A';
   13710             } else if (r.foregroundServices) {
   13711                 foreground = 'S';
   13712             } else {
   13713                 foreground = ' ';
   13714             }
   13715             String procState = ProcessList.makeProcStateString(r.curProcState);
   13716             pw.print(prefix);
   13717             pw.print(r.persistent ? persistentLabel : normalLabel);
   13718             pw.print(" #");
   13719             int num = (origList.size()-1)-list.get(i).second;
   13720             if (num < 10) pw.print(' ');
   13721             pw.print(num);
   13722             pw.print(": ");
   13723             pw.print(oomAdj);
   13724             pw.print(' ');
   13725             pw.print(schedGroup);
   13726             pw.print('/');
   13727             pw.print(foreground);
   13728             pw.print('/');
   13729             pw.print(procState);
   13730             pw.print(" trm:");
   13731             if (r.trimMemoryLevel < 10) pw.print(' ');
   13732             pw.print(r.trimMemoryLevel);
   13733             pw.print(' ');
   13734             pw.print(r.toShortString());
   13735             pw.print(" (");
   13736             pw.print(r.adjType);
   13737             pw.println(')');
   13738             if (r.adjSource != null || r.adjTarget != null) {
   13739                 pw.print(prefix);
   13740                 pw.print("    ");
   13741                 if (r.adjTarget instanceof ComponentName) {
   13742                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   13743                 } else if (r.adjTarget != null) {
   13744                     pw.print(r.adjTarget.toString());
   13745                 } else {
   13746                     pw.print("{null}");
   13747                 }
   13748                 pw.print("<=");
   13749                 if (r.adjSource instanceof ProcessRecord) {
   13750                     pw.print("Proc{");
   13751                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   13752                     pw.println("}");
   13753                 } else if (r.adjSource != null) {
   13754                     pw.println(r.adjSource.toString());
   13755                 } else {
   13756                     pw.println("{null}");
   13757                 }
   13758             }
   13759             if (inclDetails) {
   13760                 pw.print(prefix);
   13761                 pw.print("    ");
   13762                 pw.print("oom: max="); pw.print(r.maxAdj);
   13763                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   13764                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   13765                 pw.print(" cur="); pw.print(r.curAdj);
   13766                 pw.print(" set="); pw.println(r.setAdj);
   13767                 pw.print(prefix);
   13768                 pw.print("    ");
   13769                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   13770                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   13771                 pw.print(" lastPss="); pw.print(r.lastPss);
   13772                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   13773                 pw.print(prefix);
   13774                 pw.print("    ");
   13775                 pw.print("cached="); pw.print(r.cached);
   13776                 pw.print(" empty="); pw.print(r.empty);
   13777                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   13778 
   13779                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   13780                     if (r.lastWakeTime != 0) {
   13781                         long wtime;
   13782                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   13783                         synchronized (stats) {
   13784                             wtime = stats.getProcessWakeTime(r.info.uid,
   13785                                     r.pid, curRealtime);
   13786                         }
   13787                         long timeUsed = wtime - r.lastWakeTime;
   13788                         pw.print(prefix);
   13789                         pw.print("    ");
   13790                         pw.print("keep awake over ");
   13791                         TimeUtils.formatDuration(realtimeSince, pw);
   13792                         pw.print(" used ");
   13793                         TimeUtils.formatDuration(timeUsed, pw);
   13794                         pw.print(" (");
   13795                         pw.print((timeUsed*100)/realtimeSince);
   13796                         pw.println("%)");
   13797                     }
   13798                     if (r.lastCpuTime != 0) {
   13799                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   13800                         pw.print(prefix);
   13801                         pw.print("    ");
   13802                         pw.print("run cpu over ");
   13803                         TimeUtils.formatDuration(uptimeSince, pw);
   13804                         pw.print(" used ");
   13805                         TimeUtils.formatDuration(timeUsed, pw);
   13806                         pw.print(" (");
   13807                         pw.print((timeUsed*100)/uptimeSince);
   13808                         pw.println("%)");
   13809                     }
   13810                 }
   13811             }
   13812         }
   13813         return true;
   13814     }
   13815 
   13816     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   13817             String[] args) {
   13818         ArrayList<ProcessRecord> procs;
   13819         synchronized (this) {
   13820             if (args != null && args.length > start
   13821                     && args[start].charAt(0) != '-') {
   13822                 procs = new ArrayList<ProcessRecord>();
   13823                 int pid = -1;
   13824                 try {
   13825                     pid = Integer.parseInt(args[start]);
   13826                 } catch (NumberFormatException e) {
   13827                 }
   13828                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13829                     ProcessRecord proc = mLruProcesses.get(i);
   13830                     if (proc.pid == pid) {
   13831                         procs.add(proc);
   13832                     } else if (allPkgs && proc.pkgList != null
   13833                             && proc.pkgList.containsKey(args[start])) {
   13834                         procs.add(proc);
   13835                     } else if (proc.processName.equals(args[start])) {
   13836                         procs.add(proc);
   13837                     }
   13838                 }
   13839                 if (procs.size() <= 0) {
   13840                     return null;
   13841                 }
   13842             } else {
   13843                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   13844             }
   13845         }
   13846         return procs;
   13847     }
   13848 
   13849     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   13850             PrintWriter pw, String[] args) {
   13851         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13852         if (procs == null) {
   13853             pw.println("No process found for: " + args[0]);
   13854             return;
   13855         }
   13856 
   13857         long uptime = SystemClock.uptimeMillis();
   13858         long realtime = SystemClock.elapsedRealtime();
   13859         pw.println("Applications Graphics Acceleration Info:");
   13860         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   13861 
   13862         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13863             ProcessRecord r = procs.get(i);
   13864             if (r.thread != null) {
   13865                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   13866                 pw.flush();
   13867                 try {
   13868                     TransferPipe tp = new TransferPipe();
   13869                     try {
   13870                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   13871                         tp.go(fd);
   13872                     } finally {
   13873                         tp.kill();
   13874                     }
   13875                 } catch (IOException e) {
   13876                     pw.println("Failure while dumping the app: " + r);
   13877                     pw.flush();
   13878                 } catch (RemoteException e) {
   13879                     pw.println("Got a RemoteException while dumping the app " + r);
   13880                     pw.flush();
   13881                 }
   13882             }
   13883         }
   13884     }
   13885 
   13886     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   13887         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13888         if (procs == null) {
   13889             pw.println("No process found for: " + args[0]);
   13890             return;
   13891         }
   13892 
   13893         pw.println("Applications Database Info:");
   13894 
   13895         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13896             ProcessRecord r = procs.get(i);
   13897             if (r.thread != null) {
   13898                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   13899                 pw.flush();
   13900                 try {
   13901                     TransferPipe tp = new TransferPipe();
   13902                     try {
   13903                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   13904                         tp.go(fd);
   13905                     } finally {
   13906                         tp.kill();
   13907                     }
   13908                 } catch (IOException e) {
   13909                     pw.println("Failure while dumping the app: " + r);
   13910                     pw.flush();
   13911                 } catch (RemoteException e) {
   13912                     pw.println("Got a RemoteException while dumping the app " + r);
   13913                     pw.flush();
   13914                 }
   13915             }
   13916         }
   13917     }
   13918 
   13919     final static class MemItem {
   13920         final boolean isProc;
   13921         final String label;
   13922         final String shortLabel;
   13923         final long pss;
   13924         final int id;
   13925         final boolean hasActivities;
   13926         ArrayList<MemItem> subitems;
   13927 
   13928         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   13929                 boolean _hasActivities) {
   13930             isProc = true;
   13931             label = _label;
   13932             shortLabel = _shortLabel;
   13933             pss = _pss;
   13934             id = _id;
   13935             hasActivities = _hasActivities;
   13936         }
   13937 
   13938         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   13939             isProc = false;
   13940             label = _label;
   13941             shortLabel = _shortLabel;
   13942             pss = _pss;
   13943             id = _id;
   13944             hasActivities = false;
   13945         }
   13946     }
   13947 
   13948     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   13949             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   13950         if (sort && !isCompact) {
   13951             Collections.sort(items, new Comparator<MemItem>() {
   13952                 @Override
   13953                 public int compare(MemItem lhs, MemItem rhs) {
   13954                     if (lhs.pss < rhs.pss) {
   13955                         return 1;
   13956                     } else if (lhs.pss > rhs.pss) {
   13957                         return -1;
   13958                     }
   13959                     return 0;
   13960                 }
   13961             });
   13962         }
   13963 
   13964         for (int i=0; i<items.size(); i++) {
   13965             MemItem mi = items.get(i);
   13966             if (!isCompact) {
   13967                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   13968             } else if (mi.isProc) {
   13969                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   13970                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   13971                 pw.println(mi.hasActivities ? ",a" : ",e");
   13972             } else {
   13973                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   13974                 pw.println(mi.pss);
   13975             }
   13976             if (mi.subitems != null) {
   13977                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   13978                         true, isCompact);
   13979             }
   13980         }
   13981     }
   13982 
   13983     // These are in KB.
   13984     static final long[] DUMP_MEM_BUCKETS = new long[] {
   13985         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   13986         120*1024, 160*1024, 200*1024,
   13987         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   13988         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   13989     };
   13990 
   13991     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   13992             boolean stackLike) {
   13993         int start = label.lastIndexOf('.');
   13994         if (start >= 0) start++;
   13995         else start = 0;
   13996         int end = label.length();
   13997         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   13998             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   13999                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   14000                 out.append(bucket);
   14001                 out.append(stackLike ? "MB." : "MB ");
   14002                 out.append(label, start, end);
   14003                 return;
   14004             }
   14005         }
   14006         out.append(memKB/1024);
   14007         out.append(stackLike ? "MB." : "MB ");
   14008         out.append(label, start, end);
   14009     }
   14010 
   14011     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   14012             ProcessList.NATIVE_ADJ,
   14013             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   14014             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   14015             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   14016             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   14017             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   14018             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   14019     };
   14020     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   14021             "Native",
   14022             "System", "Persistent", "Persistent Service", "Foreground",
   14023             "Visible", "Perceptible",
   14024             "Heavy Weight", "Backup",
   14025             "A Services", "Home",
   14026             "Previous", "B Services", "Cached"
   14027     };
   14028     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   14029             "native",
   14030             "sys", "pers", "persvc", "fore",
   14031             "vis", "percept",
   14032             "heavy", "backup",
   14033             "servicea", "home",
   14034             "prev", "serviceb", "cached"
   14035     };
   14036 
   14037     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   14038             long realtime, boolean isCheckinRequest, boolean isCompact) {
   14039         if (isCheckinRequest || isCompact) {
   14040             // short checkin version
   14041             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   14042         } else {
   14043             pw.println("Applications Memory Usage (kB):");
   14044             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   14045         }
   14046     }
   14047 
   14048     private static final int KSM_SHARED = 0;
   14049     private static final int KSM_SHARING = 1;
   14050     private static final int KSM_UNSHARED = 2;
   14051     private static final int KSM_VOLATILE = 3;
   14052 
   14053     private final long[] getKsmInfo() {
   14054         long[] longOut = new long[4];
   14055         final int[] SINGLE_LONG_FORMAT = new int[] {
   14056             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   14057         };
   14058         long[] longTmp = new long[1];
   14059         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   14060                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14061         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14062         longTmp[0] = 0;
   14063         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   14064                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14065         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14066         longTmp[0] = 0;
   14067         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   14068                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14069         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14070         longTmp[0] = 0;
   14071         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   14072                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14073         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14074         return longOut;
   14075     }
   14076 
   14077     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   14078             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   14079         boolean dumpDetails = false;
   14080         boolean dumpFullDetails = false;
   14081         boolean dumpDalvik = false;
   14082         boolean oomOnly = false;
   14083         boolean isCompact = false;
   14084         boolean localOnly = false;
   14085         boolean packages = false;
   14086 
   14087         int opti = 0;
   14088         while (opti < args.length) {
   14089             String opt = args[opti];
   14090             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   14091                 break;
   14092             }
   14093             opti++;
   14094             if ("-a".equals(opt)) {
   14095                 dumpDetails = true;
   14096                 dumpFullDetails = true;
   14097                 dumpDalvik = true;
   14098             } else if ("-d".equals(opt)) {
   14099                 dumpDalvik = true;
   14100             } else if ("-c".equals(opt)) {
   14101                 isCompact = true;
   14102             } else if ("--oom".equals(opt)) {
   14103                 oomOnly = true;
   14104             } else if ("--local".equals(opt)) {
   14105                 localOnly = true;
   14106             } else if ("--package".equals(opt)) {
   14107                 packages = true;
   14108             } else if ("-h".equals(opt)) {
   14109                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   14110                 pw.println("  -a: include all available information for each process.");
   14111                 pw.println("  -d: include dalvik details when dumping process details.");
   14112                 pw.println("  -c: dump in a compact machine-parseable representation.");
   14113                 pw.println("  --oom: only show processes organized by oom adj.");
   14114                 pw.println("  --local: only collect details locally, don't call process.");
   14115                 pw.println("  --package: interpret process arg as package, dumping all");
   14116                 pw.println("             processes that have loaded that package.");
   14117                 pw.println("If [process] is specified it can be the name or ");
   14118                 pw.println("pid of a specific process to dump.");
   14119                 return;
   14120             } else {
   14121                 pw.println("Unknown argument: " + opt + "; use -h for help");
   14122             }
   14123         }
   14124 
   14125         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   14126         long uptime = SystemClock.uptimeMillis();
   14127         long realtime = SystemClock.elapsedRealtime();
   14128         final long[] tmpLong = new long[1];
   14129 
   14130         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   14131         if (procs == null) {
   14132             // No Java processes.  Maybe they want to print a native process.
   14133             if (args != null && args.length > opti
   14134                     && args[opti].charAt(0) != '-') {
   14135                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   14136                         = new ArrayList<ProcessCpuTracker.Stats>();
   14137                 updateCpuStatsNow();
   14138                 int findPid = -1;
   14139                 try {
   14140                     findPid = Integer.parseInt(args[opti]);
   14141                 } catch (NumberFormatException e) {
   14142                 }
   14143                 synchronized (mProcessCpuTracker) {
   14144                     final int N = mProcessCpuTracker.countStats();
   14145                     for (int i=0; i<N; i++) {
   14146                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14147                         if (st.pid == findPid || (st.baseName != null
   14148                                 && st.baseName.equals(args[opti]))) {
   14149                             nativeProcs.add(st);
   14150                         }
   14151                     }
   14152                 }
   14153                 if (nativeProcs.size() > 0) {
   14154                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   14155                             isCompact);
   14156                     Debug.MemoryInfo mi = null;
   14157                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   14158                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   14159                         final int pid = r.pid;
   14160                         if (!isCheckinRequest && dumpDetails) {
   14161                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   14162                         }
   14163                         if (mi == null) {
   14164                             mi = new Debug.MemoryInfo();
   14165                         }
   14166                         if (dumpDetails || (!brief && !oomOnly)) {
   14167                             Debug.getMemoryInfo(pid, mi);
   14168                         } else {
   14169                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   14170                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   14171                         }
   14172                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14173                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   14174                         if (isCheckinRequest) {
   14175                             pw.println();
   14176                         }
   14177                     }
   14178                     return;
   14179                 }
   14180             }
   14181             pw.println("No process found for: " + args[opti]);
   14182             return;
   14183         }
   14184 
   14185         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   14186             dumpDetails = true;
   14187         }
   14188 
   14189         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   14190 
   14191         String[] innerArgs = new String[args.length-opti];
   14192         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   14193 
   14194         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   14195         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   14196         long nativePss = 0;
   14197         long dalvikPss = 0;
   14198         long otherPss = 0;
   14199         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   14200 
   14201         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   14202         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   14203                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   14204 
   14205         long totalPss = 0;
   14206         long cachedPss = 0;
   14207 
   14208         Debug.MemoryInfo mi = null;
   14209         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   14210             final ProcessRecord r = procs.get(i);
   14211             final IApplicationThread thread;
   14212             final int pid;
   14213             final int oomAdj;
   14214             final boolean hasActivities;
   14215             synchronized (this) {
   14216                 thread = r.thread;
   14217                 pid = r.pid;
   14218                 oomAdj = r.getSetAdjWithServices();
   14219                 hasActivities = r.activities.size() > 0;
   14220             }
   14221             if (thread != null) {
   14222                 if (!isCheckinRequest && dumpDetails) {
   14223                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   14224                 }
   14225                 if (mi == null) {
   14226                     mi = new Debug.MemoryInfo();
   14227                 }
   14228                 if (dumpDetails || (!brief && !oomOnly)) {
   14229                     Debug.getMemoryInfo(pid, mi);
   14230                 } else {
   14231                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   14232                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   14233                 }
   14234                 if (dumpDetails) {
   14235                     if (localOnly) {
   14236                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14237                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
   14238                         if (isCheckinRequest) {
   14239                             pw.println();
   14240                         }
   14241                     } else {
   14242                         try {
   14243                             pw.flush();
   14244                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   14245                                     dumpDalvik, innerArgs);
   14246                         } catch (RemoteException e) {
   14247                             if (!isCheckinRequest) {
   14248                                 pw.println("Got RemoteException!");
   14249                                 pw.flush();
   14250                             }
   14251                         }
   14252                     }
   14253                 }
   14254 
   14255                 final long myTotalPss = mi.getTotalPss();
   14256                 final long myTotalUss = mi.getTotalUss();
   14257 
   14258                 synchronized (this) {
   14259                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   14260                         // Record this for posterity if the process has been stable.
   14261                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   14262                     }
   14263                 }
   14264 
   14265                 if (!isCheckinRequest && mi != null) {
   14266                     totalPss += myTotalPss;
   14267                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   14268                             (hasActivities ? " / activities)" : ")"),
   14269                             r.processName, myTotalPss, pid, hasActivities);
   14270                     procMems.add(pssItem);
   14271                     procMemsMap.put(pid, pssItem);
   14272 
   14273                     nativePss += mi.nativePss;
   14274                     dalvikPss += mi.dalvikPss;
   14275                     otherPss += mi.otherPss;
   14276                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14277                         long mem = mi.getOtherPss(j);
   14278                         miscPss[j] += mem;
   14279                         otherPss -= mem;
   14280                     }
   14281 
   14282                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14283                         cachedPss += myTotalPss;
   14284                     }
   14285 
   14286                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   14287                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   14288                                 || oomIndex == (oomPss.length-1)) {
   14289                             oomPss[oomIndex] += myTotalPss;
   14290                             if (oomProcs[oomIndex] == null) {
   14291                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   14292                             }
   14293                             oomProcs[oomIndex].add(pssItem);
   14294                             break;
   14295                         }
   14296                     }
   14297                 }
   14298             }
   14299         }
   14300 
   14301         long nativeProcTotalPss = 0;
   14302 
   14303         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   14304             // If we are showing aggregations, also look for native processes to
   14305             // include so that our aggregations are more accurate.
   14306             updateCpuStatsNow();
   14307             mi = null;
   14308             synchronized (mProcessCpuTracker) {
   14309                 final int N = mProcessCpuTracker.countStats();
   14310                 for (int i=0; i<N; i++) {
   14311                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14312                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   14313                         if (mi == null) {
   14314                             mi = new Debug.MemoryInfo();
   14315                         }
   14316                         if (!brief && !oomOnly) {
   14317                             Debug.getMemoryInfo(st.pid, mi);
   14318                         } else {
   14319                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   14320                             mi.nativePrivateDirty = (int)tmpLong[0];
   14321                         }
   14322 
   14323                         final long myTotalPss = mi.getTotalPss();
   14324                         totalPss += myTotalPss;
   14325                         nativeProcTotalPss += myTotalPss;
   14326 
   14327                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   14328                                 st.name, myTotalPss, st.pid, false);
   14329                         procMems.add(pssItem);
   14330 
   14331                         nativePss += mi.nativePss;
   14332                         dalvikPss += mi.dalvikPss;
   14333                         otherPss += mi.otherPss;
   14334                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14335                             long mem = mi.getOtherPss(j);
   14336                             miscPss[j] += mem;
   14337                             otherPss -= mem;
   14338                         }
   14339                         oomPss[0] += myTotalPss;
   14340                         if (oomProcs[0] == null) {
   14341                             oomProcs[0] = new ArrayList<MemItem>();
   14342                         }
   14343                         oomProcs[0].add(pssItem);
   14344                     }
   14345                 }
   14346             }
   14347 
   14348             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   14349 
   14350             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   14351             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   14352             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   14353             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14354                 String label = Debug.MemoryInfo.getOtherLabel(j);
   14355                 catMems.add(new MemItem(label, label, miscPss[j], j));
   14356             }
   14357 
   14358             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   14359             for (int j=0; j<oomPss.length; j++) {
   14360                 if (oomPss[j] != 0) {
   14361                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   14362                             : DUMP_MEM_OOM_LABEL[j];
   14363                     MemItem item = new MemItem(label, label, oomPss[j],
   14364                             DUMP_MEM_OOM_ADJ[j]);
   14365                     item.subitems = oomProcs[j];
   14366                     oomMems.add(item);
   14367                 }
   14368             }
   14369 
   14370             if (!brief && !oomOnly && !isCompact) {
   14371                 pw.println();
   14372                 pw.println("Total PSS by process:");
   14373                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   14374                 pw.println();
   14375             }
   14376             if (!isCompact) {
   14377                 pw.println("Total PSS by OOM adjustment:");
   14378             }
   14379             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   14380             if (!brief && !oomOnly) {
   14381                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   14382                 if (!isCompact) {
   14383                     out.println();
   14384                     out.println("Total PSS by category:");
   14385                 }
   14386                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   14387             }
   14388             if (!isCompact) {
   14389                 pw.println();
   14390             }
   14391             MemInfoReader memInfo = new MemInfoReader();
   14392             memInfo.readMemInfo();
   14393             if (nativeProcTotalPss > 0) {
   14394                 synchronized (this) {
   14395                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
   14396                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
   14397                             memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
   14398                 }
   14399             }
   14400             if (!brief) {
   14401                 if (!isCompact) {
   14402                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   14403                     pw.print(" kB (status ");
   14404                     switch (mLastMemoryLevel) {
   14405                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   14406                             pw.println("normal)");
   14407                             break;
   14408                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   14409                             pw.println("moderate)");
   14410                             break;
   14411                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   14412                             pw.println("low)");
   14413                             break;
   14414                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   14415                             pw.println("critical)");
   14416                             break;
   14417                         default:
   14418                             pw.print(mLastMemoryLevel);
   14419                             pw.println(")");
   14420                             break;
   14421                     }
   14422                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   14423                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   14424                             pw.print(cachedPss); pw.print(" cached pss + ");
   14425                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
   14426                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   14427                 } else {
   14428                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   14429                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   14430                             + memInfo.getFreeSizeKb()); pw.print(",");
   14431                     pw.println(totalPss - cachedPss);
   14432                 }
   14433             }
   14434             if (!isCompact) {
   14435                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   14436                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
   14437                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   14438                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
   14439                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   14440                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   14441                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
   14442             }
   14443             if (!brief) {
   14444                 if (memInfo.getZramTotalSizeKb() != 0) {
   14445                     if (!isCompact) {
   14446                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   14447                                 pw.print(" kB physical used for ");
   14448                                 pw.print(memInfo.getSwapTotalSizeKb()
   14449                                         - memInfo.getSwapFreeSizeKb());
   14450                                 pw.print(" kB in swap (");
   14451                                 pw.print(memInfo.getSwapTotalSizeKb());
   14452                                 pw.println(" kB total swap)");
   14453                     } else {
   14454                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   14455                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   14456                                 pw.println(memInfo.getSwapFreeSizeKb());
   14457                     }
   14458                 }
   14459                 final long[] ksm = getKsmInfo();
   14460                 if (!isCompact) {
   14461                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   14462                             || ksm[KSM_VOLATILE] != 0) {
   14463                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
   14464                                 pw.print(" kB saved from shared ");
   14465                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
   14466                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
   14467                                 pw.print(" kB unshared; ");
   14468                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
   14469                     }
   14470                     pw.print("   Tuning: ");
   14471                     pw.print(ActivityManager.staticGetMemoryClass());
   14472                     pw.print(" (large ");
   14473                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14474                     pw.print("), oom ");
   14475                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14476                     pw.print(" kB");
   14477                     pw.print(", restore limit ");
   14478                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   14479                     pw.print(" kB");
   14480                     if (ActivityManager.isLowRamDeviceStatic()) {
   14481                         pw.print(" (low-ram)");
   14482                     }
   14483                     if (ActivityManager.isHighEndGfx()) {
   14484                         pw.print(" (high-end-gfx)");
   14485                     }
   14486                     pw.println();
   14487                 } else {
   14488                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   14489                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   14490                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   14491                     pw.print("tuning,");
   14492                     pw.print(ActivityManager.staticGetMemoryClass());
   14493                     pw.print(',');
   14494                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14495                     pw.print(',');
   14496                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14497                     if (ActivityManager.isLowRamDeviceStatic()) {
   14498                         pw.print(",low-ram");
   14499                     }
   14500                     if (ActivityManager.isHighEndGfx()) {
   14501                         pw.print(",high-end-gfx");
   14502                     }
   14503                     pw.println();
   14504                 }
   14505             }
   14506         }
   14507     }
   14508 
   14509     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   14510             long memtrack, String name) {
   14511         sb.append("  ");
   14512         sb.append(ProcessList.makeOomAdjString(oomAdj));
   14513         sb.append(' ');
   14514         sb.append(ProcessList.makeProcStateString(procState));
   14515         sb.append(' ');
   14516         ProcessList.appendRamKb(sb, pss);
   14517         sb.append(" kB: ");
   14518         sb.append(name);
   14519         if (memtrack > 0) {
   14520             sb.append(" (");
   14521             sb.append(memtrack);
   14522             sb.append(" kB memtrack)");
   14523         }
   14524     }
   14525 
   14526     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   14527         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   14528         sb.append(" (pid ");
   14529         sb.append(mi.pid);
   14530         sb.append(") ");
   14531         sb.append(mi.adjType);
   14532         sb.append('\n');
   14533         if (mi.adjReason != null) {
   14534             sb.append("                      ");
   14535             sb.append(mi.adjReason);
   14536             sb.append('\n');
   14537         }
   14538     }
   14539 
   14540     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   14541         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   14542         for (int i=0, N=memInfos.size(); i<N; i++) {
   14543             ProcessMemInfo mi = memInfos.get(i);
   14544             infoMap.put(mi.pid, mi);
   14545         }
   14546         updateCpuStatsNow();
   14547         long[] memtrackTmp = new long[1];
   14548         synchronized (mProcessCpuTracker) {
   14549             final int N = mProcessCpuTracker.countStats();
   14550             for (int i=0; i<N; i++) {
   14551                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14552                 if (st.vsize > 0) {
   14553                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
   14554                     if (pss > 0) {
   14555                         if (infoMap.indexOfKey(st.pid) < 0) {
   14556                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   14557                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   14558                             mi.pss = pss;
   14559                             mi.memtrack = memtrackTmp[0];
   14560                             memInfos.add(mi);
   14561                         }
   14562                     }
   14563                 }
   14564             }
   14565         }
   14566 
   14567         long totalPss = 0;
   14568         long totalMemtrack = 0;
   14569         for (int i=0, N=memInfos.size(); i<N; i++) {
   14570             ProcessMemInfo mi = memInfos.get(i);
   14571             if (mi.pss == 0) {
   14572                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   14573                 mi.memtrack = memtrackTmp[0];
   14574             }
   14575             totalPss += mi.pss;
   14576             totalMemtrack += mi.memtrack;
   14577         }
   14578         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   14579             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   14580                 if (lhs.oomAdj != rhs.oomAdj) {
   14581                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   14582                 }
   14583                 if (lhs.pss != rhs.pss) {
   14584                     return lhs.pss < rhs.pss ? 1 : -1;
   14585                 }
   14586                 return 0;
   14587             }
   14588         });
   14589 
   14590         StringBuilder tag = new StringBuilder(128);
   14591         StringBuilder stack = new StringBuilder(128);
   14592         tag.append("Low on memory -- ");
   14593         appendMemBucket(tag, totalPss, "total", false);
   14594         appendMemBucket(stack, totalPss, "total", true);
   14595 
   14596         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   14597         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   14598         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   14599 
   14600         boolean firstLine = true;
   14601         int lastOomAdj = Integer.MIN_VALUE;
   14602         long extraNativeRam = 0;
   14603         long extraNativeMemtrack = 0;
   14604         long cachedPss = 0;
   14605         for (int i=0, N=memInfos.size(); i<N; i++) {
   14606             ProcessMemInfo mi = memInfos.get(i);
   14607 
   14608             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14609                 cachedPss += mi.pss;
   14610             }
   14611 
   14612             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   14613                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   14614                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   14615                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   14616                 if (lastOomAdj != mi.oomAdj) {
   14617                     lastOomAdj = mi.oomAdj;
   14618                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14619                         tag.append(" / ");
   14620                     }
   14621                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   14622                         if (firstLine) {
   14623                             stack.append(":");
   14624                             firstLine = false;
   14625                         }
   14626                         stack.append("\n\t at ");
   14627                     } else {
   14628                         stack.append("$");
   14629                     }
   14630                 } else {
   14631                     tag.append(" ");
   14632                     stack.append("$");
   14633                 }
   14634                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14635                     appendMemBucket(tag, mi.pss, mi.name, false);
   14636                 }
   14637                 appendMemBucket(stack, mi.pss, mi.name, true);
   14638                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   14639                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   14640                     stack.append("(");
   14641                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   14642                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   14643                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   14644                             stack.append(":");
   14645                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   14646                         }
   14647                     }
   14648                     stack.append(")");
   14649                 }
   14650             }
   14651 
   14652             appendMemInfo(fullNativeBuilder, mi);
   14653             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   14654                 // The short form only has native processes that are >= 512K.
   14655                 if (mi.pss >= 512) {
   14656                     appendMemInfo(shortNativeBuilder, mi);
   14657                 } else {
   14658                     extraNativeRam += mi.pss;
   14659                     extraNativeMemtrack += mi.memtrack;
   14660                 }
   14661             } else {
   14662                 // Short form has all other details, but if we have collected RAM
   14663                 // from smaller native processes let's dump a summary of that.
   14664                 if (extraNativeRam > 0) {
   14665                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   14666                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   14667                     shortNativeBuilder.append('\n');
   14668                     extraNativeRam = 0;
   14669                 }
   14670                 appendMemInfo(fullJavaBuilder, mi);
   14671             }
   14672         }
   14673 
   14674         fullJavaBuilder.append("           ");
   14675         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   14676         fullJavaBuilder.append(" kB: TOTAL");
   14677         if (totalMemtrack > 0) {
   14678             fullJavaBuilder.append(" (");
   14679             fullJavaBuilder.append(totalMemtrack);
   14680             fullJavaBuilder.append(" kB memtrack)");
   14681         } else {
   14682         }
   14683         fullJavaBuilder.append("\n");
   14684 
   14685         MemInfoReader memInfo = new MemInfoReader();
   14686         memInfo.readMemInfo();
   14687         final long[] infos = memInfo.getRawInfo();
   14688 
   14689         StringBuilder memInfoBuilder = new StringBuilder(1024);
   14690         Debug.getMemInfo(infos);
   14691         memInfoBuilder.append("  MemInfo: ");
   14692         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
   14693         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
   14694         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
   14695         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
   14696         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
   14697         memInfoBuilder.append("           ");
   14698         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
   14699         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
   14700         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
   14701         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
   14702         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   14703             memInfoBuilder.append("  ZRAM: ");
   14704             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
   14705             memInfoBuilder.append(" kB RAM, ");
   14706             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
   14707             memInfoBuilder.append(" kB swap total, ");
   14708             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
   14709             memInfoBuilder.append(" kB swap free\n");
   14710         }
   14711         final long[] ksm = getKsmInfo();
   14712         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   14713                 || ksm[KSM_VOLATILE] != 0) {
   14714             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
   14715             memInfoBuilder.append(" kB saved from shared ");
   14716             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
   14717             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
   14718             memInfoBuilder.append(" kB unshared; ");
   14719             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
   14720         }
   14721         memInfoBuilder.append("  Free RAM: ");
   14722         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
   14723                 + memInfo.getFreeSizeKb());
   14724         memInfoBuilder.append(" kB\n");
   14725         memInfoBuilder.append("  Used RAM: ");
   14726         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
   14727         memInfoBuilder.append(" kB\n");
   14728         memInfoBuilder.append("  Lost RAM: ");
   14729         memInfoBuilder.append(memInfo.getTotalSizeKb()
   14730                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   14731                 - memInfo.getKernelUsedSizeKb());
   14732         memInfoBuilder.append(" kB\n");
   14733         Slog.i(TAG, "Low on memory:");
   14734         Slog.i(TAG, shortNativeBuilder.toString());
   14735         Slog.i(TAG, fullJavaBuilder.toString());
   14736         Slog.i(TAG, memInfoBuilder.toString());
   14737 
   14738         StringBuilder dropBuilder = new StringBuilder(1024);
   14739         /*
   14740         StringWriter oomSw = new StringWriter();
   14741         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   14742         StringWriter catSw = new StringWriter();
   14743         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   14744         String[] emptyArgs = new String[] { };
   14745         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   14746         oomPw.flush();
   14747         String oomString = oomSw.toString();
   14748         */
   14749         dropBuilder.append("Low on memory:");
   14750         dropBuilder.append(stack);
   14751         dropBuilder.append('\n');
   14752         dropBuilder.append(fullNativeBuilder);
   14753         dropBuilder.append(fullJavaBuilder);
   14754         dropBuilder.append('\n');
   14755         dropBuilder.append(memInfoBuilder);
   14756         dropBuilder.append('\n');
   14757         /*
   14758         dropBuilder.append(oomString);
   14759         dropBuilder.append('\n');
   14760         */
   14761         StringWriter catSw = new StringWriter();
   14762         synchronized (ActivityManagerService.this) {
   14763             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   14764             String[] emptyArgs = new String[] { };
   14765             catPw.println();
   14766             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   14767             catPw.println();
   14768             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   14769                     false, false, null);
   14770             catPw.println();
   14771             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   14772             catPw.flush();
   14773         }
   14774         dropBuilder.append(catSw.toString());
   14775         addErrorToDropBox("lowmem", null, "system_server", null,
   14776                 null, tag.toString(), dropBuilder.toString(), null, null);
   14777         //Slog.i(TAG, "Sent to dropbox:");
   14778         //Slog.i(TAG, dropBuilder.toString());
   14779         synchronized (ActivityManagerService.this) {
   14780             long now = SystemClock.uptimeMillis();
   14781             if (mLastMemUsageReportTime < now) {
   14782                 mLastMemUsageReportTime = now;
   14783             }
   14784         }
   14785     }
   14786 
   14787     /**
   14788      * Searches array of arguments for the specified string
   14789      * @param args array of argument strings
   14790      * @param value value to search for
   14791      * @return true if the value is contained in the array
   14792      */
   14793     private static boolean scanArgs(String[] args, String value) {
   14794         if (args != null) {
   14795             for (String arg : args) {
   14796                 if (value.equals(arg)) {
   14797                     return true;
   14798                 }
   14799             }
   14800         }
   14801         return false;
   14802     }
   14803 
   14804     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   14805             ContentProviderRecord cpr, boolean always) {
   14806         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   14807 
   14808         if (!inLaunching || always) {
   14809             synchronized (cpr) {
   14810                 cpr.launchingApp = null;
   14811                 cpr.notifyAll();
   14812             }
   14813             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   14814             String names[] = cpr.info.authority.split(";");
   14815             for (int j = 0; j < names.length; j++) {
   14816                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   14817             }
   14818         }
   14819 
   14820         for (int i=0; i<cpr.connections.size(); i++) {
   14821             ContentProviderConnection conn = cpr.connections.get(i);
   14822             if (conn.waiting) {
   14823                 // If this connection is waiting for the provider, then we don't
   14824                 // need to mess with its process unless we are always removing
   14825                 // or for some reason the provider is not currently launching.
   14826                 if (inLaunching && !always) {
   14827                     continue;
   14828                 }
   14829             }
   14830             ProcessRecord capp = conn.client;
   14831             conn.dead = true;
   14832             if (conn.stableCount > 0) {
   14833                 if (!capp.persistent && capp.thread != null
   14834                         && capp.pid != 0
   14835                         && capp.pid != MY_PID) {
   14836                     capp.kill("depends on provider "
   14837                             + cpr.name.flattenToShortString()
   14838                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
   14839                 }
   14840             } else if (capp.thread != null && conn.provider.provider != null) {
   14841                 try {
   14842                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   14843                 } catch (RemoteException e) {
   14844                 }
   14845                 // In the protocol here, we don't expect the client to correctly
   14846                 // clean up this connection, we'll just remove it.
   14847                 cpr.connections.remove(i);
   14848                 if (conn.client.conProviders.remove(conn)) {
   14849                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   14850                 }
   14851             }
   14852         }
   14853 
   14854         if (inLaunching && always) {
   14855             mLaunchingProviders.remove(cpr);
   14856         }
   14857         return inLaunching;
   14858     }
   14859 
   14860     /**
   14861      * Main code for cleaning up a process when it has gone away.  This is
   14862      * called both as a result of the process dying, or directly when stopping
   14863      * a process when running in single process mode.
   14864      *
   14865      * @return Returns true if the given process has been restarted, so the
   14866      * app that was passed in must remain on the process lists.
   14867      */
   14868     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   14869             boolean restarting, boolean allowRestart, int index) {
   14870         if (index >= 0) {
   14871             removeLruProcessLocked(app);
   14872             ProcessList.remove(app.pid);
   14873         }
   14874 
   14875         mProcessesToGc.remove(app);
   14876         mPendingPssProcesses.remove(app);
   14877 
   14878         // Dismiss any open dialogs.
   14879         if (app.crashDialog != null && !app.forceCrashReport) {
   14880             app.crashDialog.dismiss();
   14881             app.crashDialog = null;
   14882         }
   14883         if (app.anrDialog != null) {
   14884             app.anrDialog.dismiss();
   14885             app.anrDialog = null;
   14886         }
   14887         if (app.waitDialog != null) {
   14888             app.waitDialog.dismiss();
   14889             app.waitDialog = null;
   14890         }
   14891 
   14892         app.crashing = false;
   14893         app.notResponding = false;
   14894 
   14895         app.resetPackageList(mProcessStats);
   14896         app.unlinkDeathRecipient();
   14897         app.makeInactive(mProcessStats);
   14898         app.waitingToKill = null;
   14899         app.forcingToForeground = null;
   14900         updateProcessForegroundLocked(app, false, false);
   14901         app.foregroundActivities = false;
   14902         app.hasShownUi = false;
   14903         app.treatLikeActivity = false;
   14904         app.hasAboveClient = false;
   14905         app.hasClientActivities = false;
   14906 
   14907         mServices.killServicesLocked(app, allowRestart);
   14908 
   14909         boolean restart = false;
   14910 
   14911         // Remove published content providers.
   14912         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   14913             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   14914             final boolean always = app.bad || !allowRestart;
   14915             if (removeDyingProviderLocked(app, cpr, always) || always) {
   14916                 // We left the provider in the launching list, need to
   14917                 // restart it.
   14918                 restart = true;
   14919             }
   14920 
   14921             cpr.provider = null;
   14922             cpr.proc = null;
   14923         }
   14924         app.pubProviders.clear();
   14925 
   14926         // Take care of any launching providers waiting for this process.
   14927         if (checkAppInLaunchingProvidersLocked(app, false)) {
   14928             restart = true;
   14929         }
   14930 
   14931         // Unregister from connected content providers.
   14932         if (!app.conProviders.isEmpty()) {
   14933             for (int i=0; i<app.conProviders.size(); i++) {
   14934                 ContentProviderConnection conn = app.conProviders.get(i);
   14935                 conn.provider.connections.remove(conn);
   14936                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   14937                         conn.provider.name);
   14938             }
   14939             app.conProviders.clear();
   14940         }
   14941 
   14942         // At this point there may be remaining entries in mLaunchingProviders
   14943         // where we were the only one waiting, so they are no longer of use.
   14944         // Look for these and clean up if found.
   14945         // XXX Commented out for now.  Trying to figure out a way to reproduce
   14946         // the actual situation to identify what is actually going on.
   14947         if (false) {
   14948             for (int i=0; i<mLaunchingProviders.size(); i++) {
   14949                 ContentProviderRecord cpr = (ContentProviderRecord)
   14950                         mLaunchingProviders.get(i);
   14951                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   14952                     synchronized (cpr) {
   14953                         cpr.launchingApp = null;
   14954                         cpr.notifyAll();
   14955                     }
   14956                 }
   14957             }
   14958         }
   14959 
   14960         skipCurrentReceiverLocked(app);
   14961 
   14962         // Unregister any receivers.
   14963         for (int i=app.receivers.size()-1; i>=0; i--) {
   14964             removeReceiverLocked(app.receivers.valueAt(i));
   14965         }
   14966         app.receivers.clear();
   14967 
   14968         // If the app is undergoing backup, tell the backup manager about it
   14969         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   14970             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   14971                     + mBackupTarget.appInfo + " died during backup");
   14972             try {
   14973                 IBackupManager bm = IBackupManager.Stub.asInterface(
   14974                         ServiceManager.getService(Context.BACKUP_SERVICE));
   14975                 bm.agentDisconnected(app.info.packageName);
   14976             } catch (RemoteException e) {
   14977                 // can't happen; backup manager is local
   14978             }
   14979         }
   14980 
   14981         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   14982             ProcessChangeItem item = mPendingProcessChanges.get(i);
   14983             if (item.pid == app.pid) {
   14984                 mPendingProcessChanges.remove(i);
   14985                 mAvailProcessChanges.add(item);
   14986             }
   14987         }
   14988         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   14989 
   14990         // If the caller is restarting this app, then leave it in its
   14991         // current lists and let the caller take care of it.
   14992         if (restarting) {
   14993             return false;
   14994         }
   14995 
   14996         if (!app.persistent || app.isolated) {
   14997             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   14998                     "Removing non-persistent process during cleanup: " + app);
   14999             mProcessNames.remove(app.processName, app.uid);
   15000             mIsolatedProcesses.remove(app.uid);
   15001             if (mHeavyWeightProcess == app) {
   15002                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   15003                         mHeavyWeightProcess.userId, 0));
   15004                 mHeavyWeightProcess = null;
   15005             }
   15006         } else if (!app.removed) {
   15007             // This app is persistent, so we need to keep its record around.
   15008             // If it is not already on the pending app list, add it there
   15009             // and start a new process for it.
   15010             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   15011                 mPersistentStartingProcesses.add(app);
   15012                 restart = true;
   15013             }
   15014         }
   15015         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   15016                 "Clean-up removing on hold: " + app);
   15017         mProcessesOnHold.remove(app);
   15018 
   15019         if (app == mHomeProcess) {
   15020             mHomeProcess = null;
   15021         }
   15022         if (app == mPreviousProcess) {
   15023             mPreviousProcess = null;
   15024         }
   15025 
   15026         if (restart && !app.isolated) {
   15027             // We have components that still need to be running in the
   15028             // process, so re-launch it.
   15029             if (index < 0) {
   15030                 ProcessList.remove(app.pid);
   15031             }
   15032             mProcessNames.put(app.processName, app.uid, app);
   15033             startProcessLocked(app, "restart", app.processName);
   15034             return true;
   15035         } else if (app.pid > 0 && app.pid != MY_PID) {
   15036             // Goodbye!
   15037             boolean removed;
   15038             synchronized (mPidsSelfLocked) {
   15039                 mPidsSelfLocked.remove(app.pid);
   15040                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   15041             }
   15042             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   15043             if (app.isolated) {
   15044                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   15045             }
   15046             app.setPid(0);
   15047         }
   15048         return false;
   15049     }
   15050 
   15051     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   15052         // Look through the content providers we are waiting to have launched,
   15053         // and if any run in this process then either schedule a restart of
   15054         // the process or kill the client waiting for it if this process has
   15055         // gone bad.
   15056         int NL = mLaunchingProviders.size();
   15057         boolean restart = false;
   15058         for (int i=0; i<NL; i++) {
   15059             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   15060             if (cpr.launchingApp == app) {
   15061                 if (!alwaysBad && !app.bad) {
   15062                     restart = true;
   15063                 } else {
   15064                     removeDyingProviderLocked(app, cpr, true);
   15065                     // cpr should have been removed from mLaunchingProviders
   15066                     NL = mLaunchingProviders.size();
   15067                     i--;
   15068                 }
   15069             }
   15070         }
   15071         return restart;
   15072     }
   15073 
   15074     // =========================================================
   15075     // SERVICES
   15076     // =========================================================
   15077 
   15078     @Override
   15079     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   15080             int flags) {
   15081         enforceNotIsolatedCaller("getServices");
   15082         synchronized (this) {
   15083             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   15084         }
   15085     }
   15086 
   15087     @Override
   15088     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   15089         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   15090         synchronized (this) {
   15091             return mServices.getRunningServiceControlPanelLocked(name);
   15092         }
   15093     }
   15094 
   15095     @Override
   15096     public ComponentName startService(IApplicationThread caller, Intent service,
   15097             String resolvedType, int userId) {
   15098         enforceNotIsolatedCaller("startService");
   15099         // Refuse possible leaked file descriptors
   15100         if (service != null && service.hasFileDescriptors() == true) {
   15101             throw new IllegalArgumentException("File descriptors passed in Intent");
   15102         }
   15103 
   15104         if (DEBUG_SERVICE)
   15105             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   15106         synchronized(this) {
   15107             final int callingPid = Binder.getCallingPid();
   15108             final int callingUid = Binder.getCallingUid();
   15109             final long origId = Binder.clearCallingIdentity();
   15110             ComponentName res = mServices.startServiceLocked(caller, service,
   15111                     resolvedType, callingPid, callingUid, userId);
   15112             Binder.restoreCallingIdentity(origId);
   15113             return res;
   15114         }
   15115     }
   15116 
   15117     ComponentName startServiceInPackage(int uid,
   15118             Intent service, String resolvedType, int userId) {
   15119         synchronized(this) {
   15120             if (DEBUG_SERVICE)
   15121                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   15122             final long origId = Binder.clearCallingIdentity();
   15123             ComponentName res = mServices.startServiceLocked(null, service,
   15124                     resolvedType, -1, uid, userId);
   15125             Binder.restoreCallingIdentity(origId);
   15126             return res;
   15127         }
   15128     }
   15129 
   15130     @Override
   15131     public int stopService(IApplicationThread caller, Intent service,
   15132             String resolvedType, int userId) {
   15133         enforceNotIsolatedCaller("stopService");
   15134         // Refuse possible leaked file descriptors
   15135         if (service != null && service.hasFileDescriptors() == true) {
   15136             throw new IllegalArgumentException("File descriptors passed in Intent");
   15137         }
   15138 
   15139         synchronized(this) {
   15140             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   15141         }
   15142     }
   15143 
   15144     @Override
   15145     public IBinder peekService(Intent service, String resolvedType) {
   15146         enforceNotIsolatedCaller("peekService");
   15147         // Refuse possible leaked file descriptors
   15148         if (service != null && service.hasFileDescriptors() == true) {
   15149             throw new IllegalArgumentException("File descriptors passed in Intent");
   15150         }
   15151         synchronized(this) {
   15152             return mServices.peekServiceLocked(service, resolvedType);
   15153         }
   15154     }
   15155 
   15156     @Override
   15157     public boolean stopServiceToken(ComponentName className, IBinder token,
   15158             int startId) {
   15159         synchronized(this) {
   15160             return mServices.stopServiceTokenLocked(className, token, startId);
   15161         }
   15162     }
   15163 
   15164     @Override
   15165     public void setServiceForeground(ComponentName className, IBinder token,
   15166             int id, Notification notification, boolean removeNotification) {
   15167         synchronized(this) {
   15168             mServices.setServiceForegroundLocked(className, token, id, notification,
   15169                     removeNotification);
   15170         }
   15171     }
   15172 
   15173     @Override
   15174     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   15175             boolean requireFull, String name, String callerPackage) {
   15176         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
   15177                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   15178     }
   15179 
   15180     int unsafeConvertIncomingUser(int userId) {
   15181         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
   15182                 ? mCurrentUserId : userId;
   15183     }
   15184 
   15185     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   15186             int allowMode, String name, String callerPackage) {
   15187         final int callingUserId = UserHandle.getUserId(callingUid);
   15188         if (callingUserId == userId) {
   15189             return userId;
   15190         }
   15191 
   15192         // Note that we may be accessing mCurrentUserId outside of a lock...
   15193         // shouldn't be a big deal, if this is being called outside
   15194         // of a locked context there is intrinsically a race with
   15195         // the value the caller will receive and someone else changing it.
   15196         // We assume that USER_CURRENT_OR_SELF will use the current user; later
   15197         // we will switch to the calling user if access to the current user fails.
   15198         int targetUserId = unsafeConvertIncomingUser(userId);
   15199 
   15200         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   15201             final boolean allow;
   15202             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   15203                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   15204                 // If the caller has this permission, they always pass go.  And collect $200.
   15205                 allow = true;
   15206             } else if (allowMode == ALLOW_FULL_ONLY) {
   15207                 // We require full access, sucks to be you.
   15208                 allow = false;
   15209             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   15210                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
   15211                 // If the caller does not have either permission, they are always doomed.
   15212                 allow = false;
   15213             } else if (allowMode == ALLOW_NON_FULL) {
   15214                 // We are blanket allowing non-full access, you lucky caller!
   15215                 allow = true;
   15216             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
   15217                 // We may or may not allow this depending on whether the two users are
   15218                 // in the same profile.
   15219                 synchronized (mUserProfileGroupIdsSelfLocked) {
   15220                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
   15221                             UserInfo.NO_PROFILE_GROUP_ID);
   15222                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
   15223                             UserInfo.NO_PROFILE_GROUP_ID);
   15224                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
   15225                             && callingProfile == targetProfile;
   15226                 }
   15227             } else {
   15228                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
   15229             }
   15230             if (!allow) {
   15231                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   15232                     // In this case, they would like to just execute as their
   15233                     // owner user instead of failing.
   15234                     targetUserId = callingUserId;
   15235                 } else {
   15236                     StringBuilder builder = new StringBuilder(128);
   15237                     builder.append("Permission Denial: ");
   15238                     builder.append(name);
   15239                     if (callerPackage != null) {
   15240                         builder.append(" from ");
   15241                         builder.append(callerPackage);
   15242                     }
   15243                     builder.append(" asks to run as user ");
   15244                     builder.append(userId);
   15245                     builder.append(" but is calling from user ");
   15246                     builder.append(UserHandle.getUserId(callingUid));
   15247                     builder.append("; this requires ");
   15248                     builder.append(INTERACT_ACROSS_USERS_FULL);
   15249                     if (allowMode != ALLOW_FULL_ONLY) {
   15250                         builder.append(" or ");
   15251                         builder.append(INTERACT_ACROSS_USERS);
   15252                     }
   15253                     String msg = builder.toString();
   15254                     Slog.w(TAG, msg);
   15255                     throw new SecurityException(msg);
   15256                 }
   15257             }
   15258         }
   15259         if (!allowAll && targetUserId < 0) {
   15260             throw new IllegalArgumentException(
   15261                     "Call does not support special user #" + targetUserId);
   15262         }
   15263         // Check shell permission
   15264         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
   15265             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
   15266                     targetUserId)) {
   15267                 throw new SecurityException("Shell does not have permission to access user "
   15268                         + targetUserId + "\n " + Debug.getCallers(3));
   15269             }
   15270         }
   15271         return targetUserId;
   15272     }
   15273 
   15274     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   15275             String className, int flags) {
   15276         boolean result = false;
   15277         // For apps that don't have pre-defined UIDs, check for permission
   15278         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   15279             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   15280                 if (ActivityManager.checkUidPermission(
   15281                         INTERACT_ACROSS_USERS,
   15282                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   15283                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   15284                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   15285                             + " requests FLAG_SINGLE_USER, but app does not hold "
   15286                             + INTERACT_ACROSS_USERS;
   15287                     Slog.w(TAG, msg);
   15288                     throw new SecurityException(msg);
   15289                 }
   15290                 // Permission passed
   15291                 result = true;
   15292             }
   15293         } else if ("system".equals(componentProcessName)) {
   15294             result = true;
   15295         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   15296             // Phone app and persistent apps are allowed to export singleuser providers.
   15297             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   15298                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   15299         }
   15300         if (DEBUG_MU) {
   15301             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   15302                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   15303         }
   15304         return result;
   15305     }
   15306 
   15307     /**
   15308      * Checks to see if the caller is in the same app as the singleton
   15309      * component, or the component is in a special app. It allows special apps
   15310      * to export singleton components but prevents exporting singleton
   15311      * components for regular apps.
   15312      */
   15313     boolean isValidSingletonCall(int callingUid, int componentUid) {
   15314         int componentAppId = UserHandle.getAppId(componentUid);
   15315         return UserHandle.isSameApp(callingUid, componentUid)
   15316                 || componentAppId == Process.SYSTEM_UID
   15317                 || componentAppId == Process.PHONE_UID
   15318                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   15319                         == PackageManager.PERMISSION_GRANTED;
   15320     }
   15321 
   15322     public int bindService(IApplicationThread caller, IBinder token,
   15323             Intent service, String resolvedType,
   15324             IServiceConnection connection, int flags, int userId) {
   15325         enforceNotIsolatedCaller("bindService");
   15326 
   15327         // Refuse possible leaked file descriptors
   15328         if (service != null && service.hasFileDescriptors() == true) {
   15329             throw new IllegalArgumentException("File descriptors passed in Intent");
   15330         }
   15331 
   15332         synchronized(this) {
   15333             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   15334                     connection, flags, userId);
   15335         }
   15336     }
   15337 
   15338     public boolean unbindService(IServiceConnection connection) {
   15339         synchronized (this) {
   15340             return mServices.unbindServiceLocked(connection);
   15341         }
   15342     }
   15343 
   15344     public void publishService(IBinder token, Intent intent, IBinder service) {
   15345         // Refuse possible leaked file descriptors
   15346         if (intent != null && intent.hasFileDescriptors() == true) {
   15347             throw new IllegalArgumentException("File descriptors passed in Intent");
   15348         }
   15349 
   15350         synchronized(this) {
   15351             if (!(token instanceof ServiceRecord)) {
   15352                 throw new IllegalArgumentException("Invalid service token");
   15353             }
   15354             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   15355         }
   15356     }
   15357 
   15358     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   15359         // Refuse possible leaked file descriptors
   15360         if (intent != null && intent.hasFileDescriptors() == true) {
   15361             throw new IllegalArgumentException("File descriptors passed in Intent");
   15362         }
   15363 
   15364         synchronized(this) {
   15365             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   15366         }
   15367     }
   15368 
   15369     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   15370         synchronized(this) {
   15371             if (!(token instanceof ServiceRecord)) {
   15372                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   15373                 throw new IllegalArgumentException("Invalid service token");
   15374             }
   15375             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   15376         }
   15377     }
   15378 
   15379     // =========================================================
   15380     // BACKUP AND RESTORE
   15381     // =========================================================
   15382 
   15383     // Cause the target app to be launched if necessary and its backup agent
   15384     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   15385     // activity manager to announce its creation.
   15386     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   15387         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   15388         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   15389 
   15390         synchronized(this) {
   15391             // !!! TODO: currently no check here that we're already bound
   15392             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   15393             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15394             synchronized (stats) {
   15395                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   15396             }
   15397 
   15398             // Backup agent is now in use, its package can't be stopped.
   15399             try {
   15400                 AppGlobals.getPackageManager().setPackageStoppedState(
   15401                         app.packageName, false, UserHandle.getUserId(app.uid));
   15402             } catch (RemoteException e) {
   15403             } catch (IllegalArgumentException e) {
   15404                 Slog.w(TAG, "Failed trying to unstop package "
   15405                         + app.packageName + ": " + e);
   15406             }
   15407 
   15408             BackupRecord r = new BackupRecord(ss, app, backupMode);
   15409             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   15410                     ? new ComponentName(app.packageName, app.backupAgentName)
   15411                     : new ComponentName("android", "FullBackupAgent");
   15412             // startProcessLocked() returns existing proc's record if it's already running
   15413             ProcessRecord proc = startProcessLocked(app.processName, app,
   15414                     false, 0, "backup", hostingName, false, false, false);
   15415             if (proc == null) {
   15416                 Slog.e(TAG, "Unable to start backup agent process " + r);
   15417                 return false;
   15418             }
   15419 
   15420             r.app = proc;
   15421             mBackupTarget = r;
   15422             mBackupAppName = app.packageName;
   15423 
   15424             // Try not to kill the process during backup
   15425             updateOomAdjLocked(proc);
   15426 
   15427             // If the process is already attached, schedule the creation of the backup agent now.
   15428             // If it is not yet live, this will be done when it attaches to the framework.
   15429             if (proc.thread != null) {
   15430                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   15431                 try {
   15432                     proc.thread.scheduleCreateBackupAgent(app,
   15433                             compatibilityInfoForPackageLocked(app), backupMode);
   15434                 } catch (RemoteException e) {
   15435                     // Will time out on the backup manager side
   15436                 }
   15437             } else {
   15438                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   15439             }
   15440             // Invariants: at this point, the target app process exists and the application
   15441             // is either already running or in the process of coming up.  mBackupTarget and
   15442             // mBackupAppName describe the app, so that when it binds back to the AM we
   15443             // know that it's scheduled for a backup-agent operation.
   15444         }
   15445 
   15446         return true;
   15447     }
   15448 
   15449     @Override
   15450     public void clearPendingBackup() {
   15451         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   15452         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   15453 
   15454         synchronized (this) {
   15455             mBackupTarget = null;
   15456             mBackupAppName = null;
   15457         }
   15458     }
   15459 
   15460     // A backup agent has just come up
   15461     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   15462         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   15463                 + " = " + agent);
   15464 
   15465         synchronized(this) {
   15466             if (!agentPackageName.equals(mBackupAppName)) {
   15467                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   15468                 return;
   15469             }
   15470         }
   15471 
   15472         long oldIdent = Binder.clearCallingIdentity();
   15473         try {
   15474             IBackupManager bm = IBackupManager.Stub.asInterface(
   15475                     ServiceManager.getService(Context.BACKUP_SERVICE));
   15476             bm.agentConnected(agentPackageName, agent);
   15477         } catch (RemoteException e) {
   15478             // can't happen; the backup manager service is local
   15479         } catch (Exception e) {
   15480             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   15481             e.printStackTrace();
   15482         } finally {
   15483             Binder.restoreCallingIdentity(oldIdent);
   15484         }
   15485     }
   15486 
   15487     // done with this agent
   15488     public void unbindBackupAgent(ApplicationInfo appInfo) {
   15489         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   15490         if (appInfo == null) {
   15491             Slog.w(TAG, "unbind backup agent for null app");
   15492             return;
   15493         }
   15494 
   15495         synchronized(this) {
   15496             try {
   15497                 if (mBackupAppName == null) {
   15498                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   15499                     return;
   15500                 }
   15501 
   15502                 if (!mBackupAppName.equals(appInfo.packageName)) {
   15503                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   15504                     return;
   15505                 }
   15506 
   15507                 // Not backing this app up any more; reset its OOM adjustment
   15508                 final ProcessRecord proc = mBackupTarget.app;
   15509                 updateOomAdjLocked(proc);
   15510 
   15511                 // If the app crashed during backup, 'thread' will be null here
   15512                 if (proc.thread != null) {
   15513                     try {
   15514                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   15515                                 compatibilityInfoForPackageLocked(appInfo));
   15516                     } catch (Exception e) {
   15517                         Slog.e(TAG, "Exception when unbinding backup agent:");
   15518                         e.printStackTrace();
   15519                     }
   15520                 }
   15521             } finally {
   15522                 mBackupTarget = null;
   15523                 mBackupAppName = null;
   15524             }
   15525         }
   15526     }
   15527     // =========================================================
   15528     // BROADCASTS
   15529     // =========================================================
   15530 
   15531     private final List getStickiesLocked(String action, IntentFilter filter,
   15532             List cur, int userId) {
   15533         final ContentResolver resolver = mContext.getContentResolver();
   15534         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   15535         if (stickies == null) {
   15536             return cur;
   15537         }
   15538         final ArrayList<Intent> list = stickies.get(action);
   15539         if (list == null) {
   15540             return cur;
   15541         }
   15542         int N = list.size();
   15543         for (int i=0; i<N; i++) {
   15544             Intent intent = list.get(i);
   15545             if (filter.match(resolver, intent, true, TAG) >= 0) {
   15546                 if (cur == null) {
   15547                     cur = new ArrayList<Intent>();
   15548                 }
   15549                 cur.add(intent);
   15550             }
   15551         }
   15552         return cur;
   15553     }
   15554 
   15555     boolean isPendingBroadcastProcessLocked(int pid) {
   15556         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   15557                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   15558     }
   15559 
   15560     void skipPendingBroadcastLocked(int pid) {
   15561             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   15562             for (BroadcastQueue queue : mBroadcastQueues) {
   15563                 queue.skipPendingBroadcastLocked(pid);
   15564             }
   15565     }
   15566 
   15567     // The app just attached; send any pending broadcasts that it should receive
   15568     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   15569         boolean didSomething = false;
   15570         for (BroadcastQueue queue : mBroadcastQueues) {
   15571             didSomething |= queue.sendPendingBroadcastsLocked(app);
   15572         }
   15573         return didSomething;
   15574     }
   15575 
   15576     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   15577             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   15578         enforceNotIsolatedCaller("registerReceiver");
   15579         int callingUid;
   15580         int callingPid;
   15581         synchronized(this) {
   15582             ProcessRecord callerApp = null;
   15583             if (caller != null) {
   15584                 callerApp = getRecordForAppLocked(caller);
   15585                 if (callerApp == null) {
   15586                     throw new SecurityException(
   15587                             "Unable to find app for caller " + caller
   15588                             + " (pid=" + Binder.getCallingPid()
   15589                             + ") when registering receiver " + receiver);
   15590                 }
   15591                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   15592                         !callerApp.pkgList.containsKey(callerPackage) &&
   15593                         !"android".equals(callerPackage)) {
   15594                     throw new SecurityException("Given caller package " + callerPackage
   15595                             + " is not running in process " + callerApp);
   15596                 }
   15597                 callingUid = callerApp.info.uid;
   15598                 callingPid = callerApp.pid;
   15599             } else {
   15600                 callerPackage = null;
   15601                 callingUid = Binder.getCallingUid();
   15602                 callingPid = Binder.getCallingPid();
   15603             }
   15604 
   15605             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   15606                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   15607 
   15608             List allSticky = null;
   15609 
   15610             // Look for any matching sticky broadcasts...
   15611             Iterator actions = filter.actionsIterator();
   15612             if (actions != null) {
   15613                 while (actions.hasNext()) {
   15614                     String action = (String)actions.next();
   15615                     allSticky = getStickiesLocked(action, filter, allSticky,
   15616                             UserHandle.USER_ALL);
   15617                     allSticky = getStickiesLocked(action, filter, allSticky,
   15618                             UserHandle.getUserId(callingUid));
   15619                 }
   15620             } else {
   15621                 allSticky = getStickiesLocked(null, filter, allSticky,
   15622                         UserHandle.USER_ALL);
   15623                 allSticky = getStickiesLocked(null, filter, allSticky,
   15624                         UserHandle.getUserId(callingUid));
   15625             }
   15626 
   15627             // The first sticky in the list is returned directly back to
   15628             // the client.
   15629             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   15630 
   15631             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   15632                     + ": " + sticky);
   15633 
   15634             if (receiver == null) {
   15635                 return sticky;
   15636             }
   15637 
   15638             ReceiverList rl
   15639                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   15640             if (rl == null) {
   15641                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   15642                         userId, receiver);
   15643                 if (rl.app != null) {
   15644                     rl.app.receivers.add(rl);
   15645                 } else {
   15646                     try {
   15647                         receiver.asBinder().linkToDeath(rl, 0);
   15648                     } catch (RemoteException e) {
   15649                         return sticky;
   15650                     }
   15651                     rl.linkedToDeath = true;
   15652                 }
   15653                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   15654             } else if (rl.uid != callingUid) {
   15655                 throw new IllegalArgumentException(
   15656                         "Receiver requested to register for uid " + callingUid
   15657                         + " was previously registered for uid " + rl.uid);
   15658             } else if (rl.pid != callingPid) {
   15659                 throw new IllegalArgumentException(
   15660                         "Receiver requested to register for pid " + callingPid
   15661                         + " was previously registered for pid " + rl.pid);
   15662             } else if (rl.userId != userId) {
   15663                 throw new IllegalArgumentException(
   15664                         "Receiver requested to register for user " + userId
   15665                         + " was previously registered for user " + rl.userId);
   15666             }
   15667             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   15668                     permission, callingUid, userId);
   15669             rl.add(bf);
   15670             if (!bf.debugCheck()) {
   15671                 Slog.w(TAG, "==> For Dynamic broadast");
   15672             }
   15673             mReceiverResolver.addFilter(bf);
   15674 
   15675             // Enqueue broadcasts for all existing stickies that match
   15676             // this filter.
   15677             if (allSticky != null) {
   15678                 ArrayList receivers = new ArrayList();
   15679                 receivers.add(bf);
   15680 
   15681                 int N = allSticky.size();
   15682                 for (int i=0; i<N; i++) {
   15683                     Intent intent = (Intent)allSticky.get(i);
   15684                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   15685                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   15686                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   15687                             null, null, false, true, true, -1);
   15688                     queue.enqueueParallelBroadcastLocked(r);
   15689                     queue.scheduleBroadcastsLocked();
   15690                 }
   15691             }
   15692 
   15693             return sticky;
   15694         }
   15695     }
   15696 
   15697     public void unregisterReceiver(IIntentReceiver receiver) {
   15698         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   15699 
   15700         final long origId = Binder.clearCallingIdentity();
   15701         try {
   15702             boolean doTrim = false;
   15703 
   15704             synchronized(this) {
   15705                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   15706                 if (rl != null) {
   15707                     if (rl.curBroadcast != null) {
   15708                         BroadcastRecord r = rl.curBroadcast;
   15709                         final boolean doNext = finishReceiverLocked(
   15710                                 receiver.asBinder(), r.resultCode, r.resultData,
   15711                                 r.resultExtras, r.resultAbort);
   15712                         if (doNext) {
   15713                             doTrim = true;
   15714                             r.queue.processNextBroadcast(false);
   15715                         }
   15716                     }
   15717 
   15718                     if (rl.app != null) {
   15719                         rl.app.receivers.remove(rl);
   15720                     }
   15721                     removeReceiverLocked(rl);
   15722                     if (rl.linkedToDeath) {
   15723                         rl.linkedToDeath = false;
   15724                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   15725                     }
   15726                 }
   15727             }
   15728 
   15729             // If we actually concluded any broadcasts, we might now be able
   15730             // to trim the recipients' apps from our working set
   15731             if (doTrim) {
   15732                 trimApplications();
   15733                 return;
   15734             }
   15735 
   15736         } finally {
   15737             Binder.restoreCallingIdentity(origId);
   15738         }
   15739     }
   15740 
   15741     void removeReceiverLocked(ReceiverList rl) {
   15742         mRegisteredReceivers.remove(rl.receiver.asBinder());
   15743         int N = rl.size();
   15744         for (int i=0; i<N; i++) {
   15745             mReceiverResolver.removeFilter(rl.get(i));
   15746         }
   15747     }
   15748 
   15749     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   15750         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15751             ProcessRecord r = mLruProcesses.get(i);
   15752             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   15753                 try {
   15754                     r.thread.dispatchPackageBroadcast(cmd, packages);
   15755                 } catch (RemoteException ex) {
   15756                 }
   15757             }
   15758         }
   15759     }
   15760 
   15761     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   15762             int callingUid, int[] users) {
   15763         List<ResolveInfo> receivers = null;
   15764         try {
   15765             HashSet<ComponentName> singleUserReceivers = null;
   15766             boolean scannedFirstReceivers = false;
   15767             for (int user : users) {
   15768                 // Skip users that have Shell restrictions
   15769                 if (callingUid == Process.SHELL_UID
   15770                         && getUserManagerLocked().hasUserRestriction(
   15771                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
   15772                     continue;
   15773                 }
   15774                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   15775                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   15776                 if (user != 0 && newReceivers != null) {
   15777                     // If this is not the primary user, we need to check for
   15778                     // any receivers that should be filtered out.
   15779                     for (int i=0; i<newReceivers.size(); i++) {
   15780                         ResolveInfo ri = newReceivers.get(i);
   15781                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   15782                             newReceivers.remove(i);
   15783                             i--;
   15784                         }
   15785                     }
   15786                 }
   15787                 if (newReceivers != null && newReceivers.size() == 0) {
   15788                     newReceivers = null;
   15789                 }
   15790                 if (receivers == null) {
   15791                     receivers = newReceivers;
   15792                 } else if (newReceivers != null) {
   15793                     // We need to concatenate the additional receivers
   15794                     // found with what we have do far.  This would be easy,
   15795                     // but we also need to de-dup any receivers that are
   15796                     // singleUser.
   15797                     if (!scannedFirstReceivers) {
   15798                         // Collect any single user receivers we had already retrieved.
   15799                         scannedFirstReceivers = true;
   15800                         for (int i=0; i<receivers.size(); i++) {
   15801                             ResolveInfo ri = receivers.get(i);
   15802                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15803                                 ComponentName cn = new ComponentName(
   15804                                         ri.activityInfo.packageName, ri.activityInfo.name);
   15805                                 if (singleUserReceivers == null) {
   15806                                     singleUserReceivers = new HashSet<ComponentName>();
   15807                                 }
   15808                                 singleUserReceivers.add(cn);
   15809                             }
   15810                         }
   15811                     }
   15812                     // Add the new results to the existing results, tracking
   15813                     // and de-dupping single user receivers.
   15814                     for (int i=0; i<newReceivers.size(); i++) {
   15815                         ResolveInfo ri = newReceivers.get(i);
   15816                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15817                             ComponentName cn = new ComponentName(
   15818                                     ri.activityInfo.packageName, ri.activityInfo.name);
   15819                             if (singleUserReceivers == null) {
   15820                                 singleUserReceivers = new HashSet<ComponentName>();
   15821                             }
   15822                             if (!singleUserReceivers.contains(cn)) {
   15823                                 singleUserReceivers.add(cn);
   15824                                 receivers.add(ri);
   15825                             }
   15826                         } else {
   15827                             receivers.add(ri);
   15828                         }
   15829                     }
   15830                 }
   15831             }
   15832         } catch (RemoteException ex) {
   15833             // pm is in same process, this will never happen.
   15834         }
   15835         return receivers;
   15836     }
   15837 
   15838     private final int broadcastIntentLocked(ProcessRecord callerApp,
   15839             String callerPackage, Intent intent, String resolvedType,
   15840             IIntentReceiver resultTo, int resultCode, String resultData,
   15841             Bundle map, String requiredPermission, int appOp,
   15842             boolean ordered, boolean sticky, int callingPid, int callingUid,
   15843             int userId) {
   15844         intent = new Intent(intent);
   15845 
   15846         // By default broadcasts do not go to stopped apps.
   15847         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   15848 
   15849         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   15850             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   15851             + " ordered=" + ordered + " userid=" + userId);
   15852         if ((resultTo != null) && !ordered) {
   15853             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   15854         }
   15855 
   15856         userId = handleIncomingUser(callingPid, callingUid, userId,
   15857                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
   15858 
   15859         // Make sure that the user who is receiving this broadcast is running.
   15860         // If not, we will just skip it. Make an exception for shutdown broadcasts
   15861         // and upgrade steps.
   15862 
   15863         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
   15864             if ((callingUid != Process.SYSTEM_UID
   15865                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   15866                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   15867                 Slog.w(TAG, "Skipping broadcast of " + intent
   15868                         + ": user " + userId + " is stopped");
   15869                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   15870             }
   15871         }
   15872 
   15873         /*
   15874          * Prevent non-system code (defined here to be non-persistent
   15875          * processes) from sending protected broadcasts.
   15876          */
   15877         int callingAppId = UserHandle.getAppId(callingUid);
   15878         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   15879             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
   15880             || callingAppId == Process.NFC_UID || callingUid == 0) {
   15881             // Always okay.
   15882         } else if (callerApp == null || !callerApp.persistent) {
   15883             try {
   15884                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   15885                         intent.getAction())) {
   15886                     String msg = "Permission Denial: not allowed to send broadcast "
   15887                             + intent.getAction() + " from pid="
   15888                             + callingPid + ", uid=" + callingUid;
   15889                     Slog.w(TAG, msg);
   15890                     throw new SecurityException(msg);
   15891                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   15892                     // Special case for compatibility: we don't want apps to send this,
   15893                     // but historically it has not been protected and apps may be using it
   15894                     // to poke their own app widget.  So, instead of making it protected,
   15895                     // just limit it to the caller.
   15896                     if (callerApp == null) {
   15897                         String msg = "Permission Denial: not allowed to send broadcast "
   15898                                 + intent.getAction() + " from unknown caller.";
   15899                         Slog.w(TAG, msg);
   15900                         throw new SecurityException(msg);
   15901                     } else if (intent.getComponent() != null) {
   15902                         // They are good enough to send to an explicit component...  verify
   15903                         // it is being sent to the calling app.
   15904                         if (!intent.getComponent().getPackageName().equals(
   15905                                 callerApp.info.packageName)) {
   15906                             String msg = "Permission Denial: not allowed to send broadcast "
   15907                                     + intent.getAction() + " to "
   15908                                     + intent.getComponent().getPackageName() + " from "
   15909                                     + callerApp.info.packageName;
   15910                             Slog.w(TAG, msg);
   15911                             throw new SecurityException(msg);
   15912                         }
   15913                     } else {
   15914                         // Limit broadcast to their own package.
   15915                         intent.setPackage(callerApp.info.packageName);
   15916                     }
   15917                 }
   15918             } catch (RemoteException e) {
   15919                 Slog.w(TAG, "Remote exception", e);
   15920                 return ActivityManager.BROADCAST_SUCCESS;
   15921             }
   15922         }
   15923 
   15924         final String action = intent.getAction();
   15925         if (action != null) {
   15926             switch (action) {
   15927                 case Intent.ACTION_UID_REMOVED:
   15928                 case Intent.ACTION_PACKAGE_REMOVED:
   15929                 case Intent.ACTION_PACKAGE_CHANGED:
   15930                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   15931                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   15932                     // Handle special intents: if this broadcast is from the package
   15933                     // manager about a package being removed, we need to remove all of
   15934                     // its activities from the history stack.
   15935                     if (checkComponentPermission(
   15936                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   15937                             callingPid, callingUid, -1, true)
   15938                             != PackageManager.PERMISSION_GRANTED) {
   15939                         String msg = "Permission Denial: " + intent.getAction()
   15940                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   15941                                 + ", uid=" + callingUid + ")"
   15942                                 + " requires "
   15943                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   15944                         Slog.w(TAG, msg);
   15945                         throw new SecurityException(msg);
   15946                     }
   15947                     switch (action) {
   15948                         case Intent.ACTION_UID_REMOVED:
   15949                             final Bundle intentExtras = intent.getExtras();
   15950                             final int uid = intentExtras != null
   15951                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   15952                             if (uid >= 0) {
   15953                                 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   15954                                 synchronized (bs) {
   15955                                     bs.removeUidStatsLocked(uid);
   15956                                 }
   15957                                 mAppOpsService.uidRemoved(uid);
   15958                             }
   15959                             break;
   15960                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   15961                             // If resources are unavailable just force stop all those packages
   15962                             // and flush the attribute cache as well.
   15963                             String list[] =
   15964                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   15965                             if (list != null && list.length > 0) {
   15966                                 for (int i = 0; i < list.length; i++) {
   15967                                     forceStopPackageLocked(list[i], -1, false, true, true,
   15968                                             false, false, userId, "storage unmount");
   15969                                 }
   15970                                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15971                                 sendPackageBroadcastLocked(
   15972                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
   15973                                         userId);
   15974                             }
   15975                             break;
   15976                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   15977                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15978                             break;
   15979                         case Intent.ACTION_PACKAGE_REMOVED:
   15980                         case Intent.ACTION_PACKAGE_CHANGED:
   15981                             Uri data = intent.getData();
   15982                             String ssp;
   15983                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   15984                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   15985                                 boolean fullUninstall = removed &&
   15986                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   15987                                 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   15988                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
   15989                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
   15990                                             false, true, true, false, fullUninstall, userId,
   15991                                             removed ? "pkg removed" : "pkg changed");
   15992                                 }
   15993                                 if (removed) {
   15994                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   15995                                             new String[] {ssp}, userId);
   15996                                     if (fullUninstall) {
   15997                                         mAppOpsService.packageRemoved(
   15998                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   15999 
   16000                                         // Remove all permissions granted from/to this package
   16001                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   16002 
   16003                                         removeTasksByPackageNameLocked(ssp, userId);
   16004                                         if (userId == UserHandle.USER_OWNER) {
   16005                                             mTaskPersister.removeFromPackageCache(ssp);
   16006                                         }
   16007                                     }
   16008                                 } else {
   16009                                     removeTasksByRemovedPackageComponentsLocked(ssp, userId);
   16010                                     if (userId == UserHandle.USER_OWNER) {
   16011                                         mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
   16012                                     }
   16013                                 }
   16014                             }
   16015                             break;
   16016                     }
   16017                     break;
   16018                 case Intent.ACTION_PACKAGE_ADDED:
   16019                     // Special case for adding a package: by default turn on compatibility mode.
   16020                     Uri data = intent.getData();
   16021                     String ssp;
   16022                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   16023                         final boolean replacing =
   16024                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   16025                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   16026 
   16027                         if (replacing) {
   16028                             removeTasksByRemovedPackageComponentsLocked(ssp, userId);
   16029                         }
   16030                         if (userId == UserHandle.USER_OWNER) {
   16031                             mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
   16032                         }
   16033                     }
   16034                     break;
   16035                 case Intent.ACTION_TIMEZONE_CHANGED:
   16036                     // If this is the time zone changed action, queue up a message that will reset
   16037                     // the timezone of all currently running processes. This message will get
   16038                     // queued up before the broadcast happens.
   16039                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   16040                     break;
   16041                 case Intent.ACTION_TIME_CHANGED:
   16042                     // If the user set the time, let all running processes know.
   16043                     final int is24Hour =
   16044                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
   16045                                     : 0;
   16046                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   16047                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   16048                     synchronized (stats) {
   16049                         stats.noteCurrentTimeChangedLocked();
   16050                     }
   16051                     break;
   16052                 case Intent.ACTION_CLEAR_DNS_CACHE:
   16053                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   16054                     break;
   16055                 case Proxy.PROXY_CHANGE_ACTION:
   16056                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   16057                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   16058                     break;
   16059             }
   16060         }
   16061 
   16062         // Add to the sticky list if requested.
   16063         if (sticky) {
   16064             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   16065                     callingPid, callingUid)
   16066                     != PackageManager.PERMISSION_GRANTED) {
   16067                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   16068                         + callingPid + ", uid=" + callingUid
   16069                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   16070                 Slog.w(TAG, msg);
   16071                 throw new SecurityException(msg);
   16072             }
   16073             if (requiredPermission != null) {
   16074                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   16075                         + " and enforce permission " + requiredPermission);
   16076                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   16077             }
   16078             if (intent.getComponent() != null) {
   16079                 throw new SecurityException(
   16080                         "Sticky broadcasts can't target a specific component");
   16081             }
   16082             // We use userId directly here, since the "all" target is maintained
   16083             // as a separate set of sticky broadcasts.
   16084             if (userId != UserHandle.USER_ALL) {
   16085                 // But first, if this is not a broadcast to all users, then
   16086                 // make sure it doesn't conflict with an existing broadcast to
   16087                 // all users.
   16088                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   16089                         UserHandle.USER_ALL);
   16090                 if (stickies != null) {
   16091                     ArrayList<Intent> list = stickies.get(intent.getAction());
   16092                     if (list != null) {
   16093                         int N = list.size();
   16094                         int i;
   16095                         for (i=0; i<N; i++) {
   16096                             if (intent.filterEquals(list.get(i))) {
   16097                                 throw new IllegalArgumentException(
   16098                                         "Sticky broadcast " + intent + " for user "
   16099                                         + userId + " conflicts with existing global broadcast");
   16100                             }
   16101                         }
   16102                     }
   16103                 }
   16104             }
   16105             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   16106             if (stickies == null) {
   16107                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   16108                 mStickyBroadcasts.put(userId, stickies);
   16109             }
   16110             ArrayList<Intent> list = stickies.get(intent.getAction());
   16111             if (list == null) {
   16112                 list = new ArrayList<Intent>();
   16113                 stickies.put(intent.getAction(), list);
   16114             }
   16115             int N = list.size();
   16116             int i;
   16117             for (i=0; i<N; i++) {
   16118                 if (intent.filterEquals(list.get(i))) {
   16119                     // This sticky already exists, replace it.
   16120                     list.set(i, new Intent(intent));
   16121                     break;
   16122                 }
   16123             }
   16124             if (i >= N) {
   16125                 list.add(new Intent(intent));
   16126             }
   16127         }
   16128 
   16129         int[] users;
   16130         if (userId == UserHandle.USER_ALL) {
   16131             // Caller wants broadcast to go to all started users.
   16132             users = mStartedUserArray;
   16133         } else {
   16134             // Caller wants broadcast to go to one specific user.
   16135             users = new int[] {userId};
   16136         }
   16137 
   16138         // Figure out who all will receive this broadcast.
   16139         List receivers = null;
   16140         List<BroadcastFilter> registeredReceivers = null;
   16141         // Need to resolve the intent to interested receivers...
   16142         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   16143                  == 0) {
   16144             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   16145         }
   16146         if (intent.getComponent() == null) {
   16147             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   16148                 // Query one target user at a time, excluding shell-restricted users
   16149                 UserManagerService ums = getUserManagerLocked();
   16150                 for (int i = 0; i < users.length; i++) {
   16151                     if (ums.hasUserRestriction(
   16152                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   16153                         continue;
   16154                     }
   16155                     List<BroadcastFilter> registeredReceiversForUser =
   16156                             mReceiverResolver.queryIntent(intent,
   16157                                     resolvedType, false, users[i]);
   16158                     if (registeredReceivers == null) {
   16159                         registeredReceivers = registeredReceiversForUser;
   16160                     } else if (registeredReceiversForUser != null) {
   16161                         registeredReceivers.addAll(registeredReceiversForUser);
   16162                     }
   16163                 }
   16164             } else {
   16165                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   16166                         resolvedType, false, userId);
   16167             }
   16168         }
   16169 
   16170         final boolean replacePending =
   16171                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   16172 
   16173         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   16174                 + " replacePending=" + replacePending);
   16175 
   16176         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   16177         if (!ordered && NR > 0) {
   16178             // If we are not serializing this broadcast, then send the
   16179             // registered receivers separately so they don't wait for the
   16180             // components to be launched.
   16181             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   16182             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   16183                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   16184                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   16185                     ordered, sticky, false, userId);
   16186             if (DEBUG_BROADCAST) Slog.v(
   16187                     TAG, "Enqueueing parallel broadcast " + r);
   16188             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   16189             if (!replaced) {
   16190                 queue.enqueueParallelBroadcastLocked(r);
   16191                 queue.scheduleBroadcastsLocked();
   16192             }
   16193             registeredReceivers = null;
   16194             NR = 0;
   16195         }
   16196 
   16197         // Merge into one list.
   16198         int ir = 0;
   16199         if (receivers != null) {
   16200             // A special case for PACKAGE_ADDED: do not allow the package
   16201             // being added to see this broadcast.  This prevents them from
   16202             // using this as a back door to get run as soon as they are
   16203             // installed.  Maybe in the future we want to have a special install
   16204             // broadcast or such for apps, but we'd like to deliberately make
   16205             // this decision.
   16206             String skipPackages[] = null;
   16207             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   16208                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   16209                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   16210                 Uri data = intent.getData();
   16211                 if (data != null) {
   16212                     String pkgName = data.getSchemeSpecificPart();
   16213                     if (pkgName != null) {
   16214                         skipPackages = new String[] { pkgName };
   16215                     }
   16216                 }
   16217             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   16218                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   16219             }
   16220             if (skipPackages != null && (skipPackages.length > 0)) {
   16221                 for (String skipPackage : skipPackages) {
   16222                     if (skipPackage != null) {
   16223                         int NT = receivers.size();
   16224                         for (int it=0; it<NT; it++) {
   16225                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   16226                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   16227                                 receivers.remove(it);
   16228                                 it--;
   16229                                 NT--;
   16230                             }
   16231                         }
   16232                     }
   16233                 }
   16234             }
   16235 
   16236             int NT = receivers != null ? receivers.size() : 0;
   16237             int it = 0;
   16238             ResolveInfo curt = null;
   16239             BroadcastFilter curr = null;
   16240             while (it < NT && ir < NR) {
   16241                 if (curt == null) {
   16242                     curt = (ResolveInfo)receivers.get(it);
   16243                 }
   16244                 if (curr == null) {
   16245                     curr = registeredReceivers.get(ir);
   16246                 }
   16247                 if (curr.getPriority() >= curt.priority) {
   16248                     // Insert this broadcast record into the final list.
   16249                     receivers.add(it, curr);
   16250                     ir++;
   16251                     curr = null;
   16252                     it++;
   16253                     NT++;
   16254                 } else {
   16255                     // Skip to the next ResolveInfo in the final list.
   16256                     it++;
   16257                     curt = null;
   16258                 }
   16259             }
   16260         }
   16261         while (ir < NR) {
   16262             if (receivers == null) {
   16263                 receivers = new ArrayList();
   16264             }
   16265             receivers.add(registeredReceivers.get(ir));
   16266             ir++;
   16267         }
   16268 
   16269         if ((receivers != null && receivers.size() > 0)
   16270                 || resultTo != null) {
   16271             BroadcastQueue queue = broadcastQueueForIntent(intent);
   16272             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   16273                     callerPackage, callingPid, callingUid, resolvedType,
   16274                     requiredPermission, appOp, receivers, resultTo, resultCode,
   16275                     resultData, map, ordered, sticky, false, userId);
   16276             if (DEBUG_BROADCAST) Slog.v(
   16277                     TAG, "Enqueueing ordered broadcast " + r
   16278                     + ": prev had " + queue.mOrderedBroadcasts.size());
   16279             if (DEBUG_BROADCAST) {
   16280                 int seq = r.intent.getIntExtra("seq", -1);
   16281                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   16282             }
   16283             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   16284             if (!replaced) {
   16285                 queue.enqueueOrderedBroadcastLocked(r);
   16286                 queue.scheduleBroadcastsLocked();
   16287             }
   16288         }
   16289 
   16290         return ActivityManager.BROADCAST_SUCCESS;
   16291     }
   16292 
   16293     final Intent verifyBroadcastLocked(Intent intent) {
   16294         // Refuse possible leaked file descriptors
   16295         if (intent != null && intent.hasFileDescriptors() == true) {
   16296             throw new IllegalArgumentException("File descriptors passed in Intent");
   16297         }
   16298 
   16299         int flags = intent.getFlags();
   16300 
   16301         if (!mProcessesReady) {
   16302             // if the caller really truly claims to know what they're doing, go
   16303             // ahead and allow the broadcast without launching any receivers
   16304             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   16305                 intent = new Intent(intent);
   16306                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16307             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   16308                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   16309                         + " before boot completion");
   16310                 throw new IllegalStateException("Cannot broadcast before boot completed");
   16311             }
   16312         }
   16313 
   16314         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   16315             throw new IllegalArgumentException(
   16316                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   16317         }
   16318 
   16319         return intent;
   16320     }
   16321 
   16322     public final int broadcastIntent(IApplicationThread caller,
   16323             Intent intent, String resolvedType, IIntentReceiver resultTo,
   16324             int resultCode, String resultData, Bundle map,
   16325             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   16326         enforceNotIsolatedCaller("broadcastIntent");
   16327         synchronized(this) {
   16328             intent = verifyBroadcastLocked(intent);
   16329 
   16330             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   16331             final int callingPid = Binder.getCallingPid();
   16332             final int callingUid = Binder.getCallingUid();
   16333             final long origId = Binder.clearCallingIdentity();
   16334             int res = broadcastIntentLocked(callerApp,
   16335                     callerApp != null ? callerApp.info.packageName : null,
   16336                     intent, resolvedType, resultTo,
   16337                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   16338                     callingPid, callingUid, userId);
   16339             Binder.restoreCallingIdentity(origId);
   16340             return res;
   16341         }
   16342     }
   16343 
   16344     int broadcastIntentInPackage(String packageName, int uid,
   16345             Intent intent, String resolvedType, IIntentReceiver resultTo,
   16346             int resultCode, String resultData, Bundle map,
   16347             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   16348         synchronized(this) {
   16349             intent = verifyBroadcastLocked(intent);
   16350 
   16351             final long origId = Binder.clearCallingIdentity();
   16352             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   16353                     resultTo, resultCode, resultData, map, requiredPermission,
   16354                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   16355             Binder.restoreCallingIdentity(origId);
   16356             return res;
   16357         }
   16358     }
   16359 
   16360     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   16361         // Refuse possible leaked file descriptors
   16362         if (intent != null && intent.hasFileDescriptors() == true) {
   16363             throw new IllegalArgumentException("File descriptors passed in Intent");
   16364         }
   16365 
   16366         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   16367                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   16368 
   16369         synchronized(this) {
   16370             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   16371                     != PackageManager.PERMISSION_GRANTED) {
   16372                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   16373                         + Binder.getCallingPid()
   16374                         + ", uid=" + Binder.getCallingUid()
   16375                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   16376                 Slog.w(TAG, msg);
   16377                 throw new SecurityException(msg);
   16378             }
   16379             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   16380             if (stickies != null) {
   16381                 ArrayList<Intent> list = stickies.get(intent.getAction());
   16382                 if (list != null) {
   16383                     int N = list.size();
   16384                     int i;
   16385                     for (i=0; i<N; i++) {
   16386                         if (intent.filterEquals(list.get(i))) {
   16387                             list.remove(i);
   16388                             break;
   16389                         }
   16390                     }
   16391                     if (list.size() <= 0) {
   16392                         stickies.remove(intent.getAction());
   16393                     }
   16394                 }
   16395                 if (stickies.size() <= 0) {
   16396                     mStickyBroadcasts.remove(userId);
   16397                 }
   16398             }
   16399         }
   16400     }
   16401 
   16402     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   16403             String resultData, Bundle resultExtras, boolean resultAbort) {
   16404         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   16405         if (r == null) {
   16406             Slog.w(TAG, "finishReceiver called but not found on queue");
   16407             return false;
   16408         }
   16409 
   16410         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   16411     }
   16412 
   16413     void backgroundServicesFinishedLocked(int userId) {
   16414         for (BroadcastQueue queue : mBroadcastQueues) {
   16415             queue.backgroundServicesFinishedLocked(userId);
   16416         }
   16417     }
   16418 
   16419     public void finishReceiver(IBinder who, int resultCode, String resultData,
   16420             Bundle resultExtras, boolean resultAbort) {
   16421         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   16422 
   16423         // Refuse possible leaked file descriptors
   16424         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   16425             throw new IllegalArgumentException("File descriptors passed in Bundle");
   16426         }
   16427 
   16428         final long origId = Binder.clearCallingIdentity();
   16429         try {
   16430             boolean doNext = false;
   16431             BroadcastRecord r;
   16432 
   16433             synchronized(this) {
   16434                 r = broadcastRecordForReceiverLocked(who);
   16435                 if (r != null) {
   16436                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   16437                         resultData, resultExtras, resultAbort, true);
   16438                 }
   16439             }
   16440 
   16441             if (doNext) {
   16442                 r.queue.processNextBroadcast(false);
   16443             }
   16444             trimApplications();
   16445         } finally {
   16446             Binder.restoreCallingIdentity(origId);
   16447         }
   16448     }
   16449 
   16450     // =========================================================
   16451     // INSTRUMENTATION
   16452     // =========================================================
   16453 
   16454     public boolean startInstrumentation(ComponentName className,
   16455             String profileFile, int flags, Bundle arguments,
   16456             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   16457             int userId, String abiOverride) {
   16458         enforceNotIsolatedCaller("startInstrumentation");
   16459         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   16460                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   16461         // Refuse possible leaked file descriptors
   16462         if (arguments != null && arguments.hasFileDescriptors()) {
   16463             throw new IllegalArgumentException("File descriptors passed in Bundle");
   16464         }
   16465 
   16466         synchronized(this) {
   16467             InstrumentationInfo ii = null;
   16468             ApplicationInfo ai = null;
   16469             try {
   16470                 ii = mContext.getPackageManager().getInstrumentationInfo(
   16471                     className, STOCK_PM_FLAGS);
   16472                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   16473                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   16474             } catch (PackageManager.NameNotFoundException e) {
   16475             } catch (RemoteException e) {
   16476             }
   16477             if (ii == null) {
   16478                 reportStartInstrumentationFailure(watcher, className,
   16479                         "Unable to find instrumentation info for: " + className);
   16480                 return false;
   16481             }
   16482             if (ai == null) {
   16483                 reportStartInstrumentationFailure(watcher, className,
   16484                         "Unable to find instrumentation target package: " + ii.targetPackage);
   16485                 return false;
   16486             }
   16487 
   16488             int match = mContext.getPackageManager().checkSignatures(
   16489                     ii.targetPackage, ii.packageName);
   16490             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   16491                 String msg = "Permission Denial: starting instrumentation "
   16492                         + className + " from pid="
   16493                         + Binder.getCallingPid()
   16494                         + ", uid=" + Binder.getCallingPid()
   16495                         + " not allowed because package " + ii.packageName
   16496                         + " does not have a signature matching the target "
   16497                         + ii.targetPackage;
   16498                 reportStartInstrumentationFailure(watcher, className, msg);
   16499                 throw new SecurityException(msg);
   16500             }
   16501 
   16502             final long origId = Binder.clearCallingIdentity();
   16503             // Instrumentation can kill and relaunch even persistent processes
   16504             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   16505                     "start instr");
   16506             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   16507             app.instrumentationClass = className;
   16508             app.instrumentationInfo = ai;
   16509             app.instrumentationProfileFile = profileFile;
   16510             app.instrumentationArguments = arguments;
   16511             app.instrumentationWatcher = watcher;
   16512             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   16513             app.instrumentationResultClass = className;
   16514             Binder.restoreCallingIdentity(origId);
   16515         }
   16516 
   16517         return true;
   16518     }
   16519 
   16520     /**
   16521      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   16522      * error to the logs, but if somebody is watching, send the report there too.  This enables
   16523      * the "am" command to report errors with more information.
   16524      *
   16525      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   16526      * @param cn The component name of the instrumentation.
   16527      * @param report The error report.
   16528      */
   16529     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   16530             ComponentName cn, String report) {
   16531         Slog.w(TAG, report);
   16532         try {
   16533             if (watcher != null) {
   16534                 Bundle results = new Bundle();
   16535                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   16536                 results.putString("Error", report);
   16537                 watcher.instrumentationStatus(cn, -1, results);
   16538             }
   16539         } catch (RemoteException e) {
   16540             Slog.w(TAG, e);
   16541         }
   16542     }
   16543 
   16544     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   16545         if (app.instrumentationWatcher != null) {
   16546             try {
   16547                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   16548                 app.instrumentationWatcher.instrumentationFinished(
   16549                     app.instrumentationClass,
   16550                     resultCode,
   16551                     results);
   16552             } catch (RemoteException e) {
   16553             }
   16554         }
   16555         if (app.instrumentationUiAutomationConnection != null) {
   16556             try {
   16557                 app.instrumentationUiAutomationConnection.shutdown();
   16558             } catch (RemoteException re) {
   16559                 /* ignore */
   16560             }
   16561             // Only a UiAutomation can set this flag and now that
   16562             // it is finished we make sure it is reset to its default.
   16563             mUserIsMonkey = false;
   16564         }
   16565         app.instrumentationWatcher = null;
   16566         app.instrumentationUiAutomationConnection = null;
   16567         app.instrumentationClass = null;
   16568         app.instrumentationInfo = null;
   16569         app.instrumentationProfileFile = null;
   16570         app.instrumentationArguments = null;
   16571 
   16572         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   16573                 "finished inst");
   16574     }
   16575 
   16576     public void finishInstrumentation(IApplicationThread target,
   16577             int resultCode, Bundle results) {
   16578         int userId = UserHandle.getCallingUserId();
   16579         // Refuse possible leaked file descriptors
   16580         if (results != null && results.hasFileDescriptors()) {
   16581             throw new IllegalArgumentException("File descriptors passed in Intent");
   16582         }
   16583 
   16584         synchronized(this) {
   16585             ProcessRecord app = getRecordForAppLocked(target);
   16586             if (app == null) {
   16587                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   16588                 return;
   16589             }
   16590             final long origId = Binder.clearCallingIdentity();
   16591             finishInstrumentationLocked(app, resultCode, results);
   16592             Binder.restoreCallingIdentity(origId);
   16593         }
   16594     }
   16595 
   16596     // =========================================================
   16597     // CONFIGURATION
   16598     // =========================================================
   16599 
   16600     public ConfigurationInfo getDeviceConfigurationInfo() {
   16601         ConfigurationInfo config = new ConfigurationInfo();
   16602         synchronized (this) {
   16603             config.reqTouchScreen = mConfiguration.touchscreen;
   16604             config.reqKeyboardType = mConfiguration.keyboard;
   16605             config.reqNavigation = mConfiguration.navigation;
   16606             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   16607                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   16608                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   16609             }
   16610             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   16611                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   16612                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   16613             }
   16614             config.reqGlEsVersion = GL_ES_VERSION;
   16615         }
   16616         return config;
   16617     }
   16618 
   16619     ActivityStack getFocusedStack() {
   16620         return mStackSupervisor.getFocusedStack();
   16621     }
   16622 
   16623     public Configuration getConfiguration() {
   16624         Configuration ci;
   16625         synchronized(this) {
   16626             ci = new Configuration(mConfiguration);
   16627             ci.userSetLocale = false;
   16628         }
   16629         return ci;
   16630     }
   16631 
   16632     public void updatePersistentConfiguration(Configuration values) {
   16633         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16634                 "updateConfiguration()");
   16635         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   16636                 "updateConfiguration()");
   16637         if (values == null) {
   16638             throw new NullPointerException("Configuration must not be null");
   16639         }
   16640 
   16641         synchronized(this) {
   16642             final long origId = Binder.clearCallingIdentity();
   16643             updateConfigurationLocked(values, null, true, false);
   16644             Binder.restoreCallingIdentity(origId);
   16645         }
   16646     }
   16647 
   16648     public void updateConfiguration(Configuration values) {
   16649         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16650                 "updateConfiguration()");
   16651 
   16652         synchronized(this) {
   16653             if (values == null && mWindowManager != null) {
   16654                 // sentinel: fetch the current configuration from the window manager
   16655                 values = mWindowManager.computeNewConfiguration();
   16656             }
   16657 
   16658             if (mWindowManager != null) {
   16659                 mProcessList.applyDisplaySize(mWindowManager);
   16660             }
   16661 
   16662             final long origId = Binder.clearCallingIdentity();
   16663             if (values != null) {
   16664                 Settings.System.clearConfiguration(values);
   16665             }
   16666             updateConfigurationLocked(values, null, false, false);
   16667             Binder.restoreCallingIdentity(origId);
   16668         }
   16669     }
   16670 
   16671     /**
   16672      * Do either or both things: (1) change the current configuration, and (2)
   16673      * make sure the given activity is running with the (now) current
   16674      * configuration.  Returns true if the activity has been left running, or
   16675      * false if <var>starting</var> is being destroyed to match the new
   16676      * configuration.
   16677      * @param persistent TODO
   16678      */
   16679     boolean updateConfigurationLocked(Configuration values,
   16680             ActivityRecord starting, boolean persistent, boolean initLocale) {
   16681         int changes = 0;
   16682 
   16683         if (values != null) {
   16684             Configuration newConfig = new Configuration(mConfiguration);
   16685             changes = newConfig.updateFrom(values);
   16686             if (changes != 0) {
   16687                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   16688                     Slog.i(TAG, "Updating configuration to: " + values);
   16689                 }
   16690 
   16691                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   16692 
   16693                 if (values.locale != null && !initLocale) {
   16694                     saveLocaleLocked(values.locale,
   16695                                      !values.locale.equals(mConfiguration.locale),
   16696                                      values.userSetLocale);
   16697                 }
   16698 
   16699                 mConfigurationSeq++;
   16700                 if (mConfigurationSeq <= 0) {
   16701                     mConfigurationSeq = 1;
   16702                 }
   16703                 newConfig.seq = mConfigurationSeq;
   16704                 mConfiguration = newConfig;
   16705                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   16706                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
   16707                 //mUsageStatsService.noteStartConfig(newConfig);
   16708 
   16709                 final Configuration configCopy = new Configuration(mConfiguration);
   16710 
   16711                 // TODO: If our config changes, should we auto dismiss any currently
   16712                 // showing dialogs?
   16713                 mShowDialogs = shouldShowDialogs(newConfig);
   16714 
   16715                 AttributeCache ac = AttributeCache.instance();
   16716                 if (ac != null) {
   16717                     ac.updateConfiguration(configCopy);
   16718                 }
   16719 
   16720                 // Make sure all resources in our process are updated
   16721                 // right now, so that anyone who is going to retrieve
   16722                 // resource values after we return will be sure to get
   16723                 // the new ones.  This is especially important during
   16724                 // boot, where the first config change needs to guarantee
   16725                 // all resources have that config before following boot
   16726                 // code is executed.
   16727                 mSystemThread.applyConfigurationToResources(configCopy);
   16728 
   16729                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   16730                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   16731                     msg.obj = new Configuration(configCopy);
   16732                     mHandler.sendMessage(msg);
   16733                 }
   16734 
   16735                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   16736                     ProcessRecord app = mLruProcesses.get(i);
   16737                     try {
   16738                         if (app.thread != null) {
   16739                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   16740                                     + app.processName + " new config " + mConfiguration);
   16741                             app.thread.scheduleConfigurationChanged(configCopy);
   16742                         }
   16743                     } catch (Exception e) {
   16744                     }
   16745                 }
   16746                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   16747                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16748                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   16749                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16750                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   16751                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   16752                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   16753                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   16754                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   16755                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   16756                     broadcastIntentLocked(null, null, intent,
   16757                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16758                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16759                 }
   16760             }
   16761         }
   16762 
   16763         boolean kept = true;
   16764         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   16765         // mainStack is null during startup.
   16766         if (mainStack != null) {
   16767             if (changes != 0 && starting == null) {
   16768                 // If the configuration changed, and the caller is not already
   16769                 // in the process of starting an activity, then find the top
   16770                 // activity to check if its configuration needs to change.
   16771                 starting = mainStack.topRunningActivityLocked(null);
   16772             }
   16773 
   16774             if (starting != null) {
   16775                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   16776                 // And we need to make sure at this point that all other activities
   16777                 // are made visible with the correct configuration.
   16778                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   16779             }
   16780         }
   16781 
   16782         if (values != null && mWindowManager != null) {
   16783             mWindowManager.setNewConfiguration(mConfiguration);
   16784         }
   16785 
   16786         return kept;
   16787     }
   16788 
   16789     /**
   16790      * Decide based on the configuration whether we should shouw the ANR,
   16791      * crash, etc dialogs.  The idea is that if there is no affordnace to
   16792      * press the on-screen buttons, we shouldn't show the dialog.
   16793      *
   16794      * A thought: SystemUI might also want to get told about this, the Power
   16795      * dialog / global actions also might want different behaviors.
   16796      */
   16797     private static final boolean shouldShowDialogs(Configuration config) {
   16798         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   16799                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   16800     }
   16801 
   16802     /**
   16803      * Save the locale.  You must be inside a synchronized (this) block.
   16804      */
   16805     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   16806         if(isDiff) {
   16807             SystemProperties.set("user.language", l.getLanguage());
   16808             SystemProperties.set("user.region", l.getCountry());
   16809         }
   16810 
   16811         if(isPersist) {
   16812             SystemProperties.set("persist.sys.language", l.getLanguage());
   16813             SystemProperties.set("persist.sys.country", l.getCountry());
   16814             SystemProperties.set("persist.sys.localevar", l.getVariant());
   16815 
   16816             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
   16817         }
   16818     }
   16819 
   16820     @Override
   16821     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   16822         synchronized (this) {
   16823             ActivityRecord srec = ActivityRecord.forToken(token);
   16824             if (srec.task != null && srec.task.stack != null) {
   16825                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   16826             }
   16827         }
   16828         return false;
   16829     }
   16830 
   16831     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   16832             Intent resultData) {
   16833 
   16834         synchronized (this) {
   16835             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   16836             if (stack != null) {
   16837                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   16838             }
   16839             return false;
   16840         }
   16841     }
   16842 
   16843     public int getLaunchedFromUid(IBinder activityToken) {
   16844         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16845         if (srec == null) {
   16846             return -1;
   16847         }
   16848         return srec.launchedFromUid;
   16849     }
   16850 
   16851     public String getLaunchedFromPackage(IBinder activityToken) {
   16852         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16853         if (srec == null) {
   16854             return null;
   16855         }
   16856         return srec.launchedFromPackage;
   16857     }
   16858 
   16859     // =========================================================
   16860     // LIFETIME MANAGEMENT
   16861     // =========================================================
   16862 
   16863     // Returns which broadcast queue the app is the current [or imminent] receiver
   16864     // on, or 'null' if the app is not an active broadcast recipient.
   16865     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   16866         BroadcastRecord r = app.curReceiver;
   16867         if (r != null) {
   16868             return r.queue;
   16869         }
   16870 
   16871         // It's not the current receiver, but it might be starting up to become one
   16872         synchronized (this) {
   16873             for (BroadcastQueue queue : mBroadcastQueues) {
   16874                 r = queue.mPendingBroadcast;
   16875                 if (r != null && r.curApp == app) {
   16876                     // found it; report which queue it's in
   16877                     return queue;
   16878                 }
   16879             }
   16880         }
   16881 
   16882         return null;
   16883     }
   16884 
   16885     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   16886             ComponentName targetComponent, String targetProcess) {
   16887         if (!mTrackingAssociations) {
   16888             return null;
   16889         }
   16890         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   16891                 = mAssociations.get(targetUid);
   16892         if (components == null) {
   16893             components = new ArrayMap<>();
   16894             mAssociations.put(targetUid, components);
   16895         }
   16896         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   16897         if (sourceUids == null) {
   16898             sourceUids = new SparseArray<>();
   16899             components.put(targetComponent, sourceUids);
   16900         }
   16901         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   16902         if (sourceProcesses == null) {
   16903             sourceProcesses = new ArrayMap<>();
   16904             sourceUids.put(sourceUid, sourceProcesses);
   16905         }
   16906         Association ass = sourceProcesses.get(sourceProcess);
   16907         if (ass == null) {
   16908             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   16909                     targetProcess);
   16910             sourceProcesses.put(sourceProcess, ass);
   16911         }
   16912         ass.mCount++;
   16913         ass.mNesting++;
   16914         if (ass.mNesting == 1) {
   16915             ass.mStartTime = SystemClock.uptimeMillis();
   16916         }
   16917         return ass;
   16918     }
   16919 
   16920     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   16921             ComponentName targetComponent) {
   16922         if (!mTrackingAssociations) {
   16923             return;
   16924         }
   16925         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   16926                 = mAssociations.get(targetUid);
   16927         if (components == null) {
   16928             return;
   16929         }
   16930         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   16931         if (sourceUids == null) {
   16932             return;
   16933         }
   16934         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   16935         if (sourceProcesses == null) {
   16936             return;
   16937         }
   16938         Association ass = sourceProcesses.get(sourceProcess);
   16939         if (ass == null || ass.mNesting <= 0) {
   16940             return;
   16941         }
   16942         ass.mNesting--;
   16943         if (ass.mNesting == 0) {
   16944             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
   16945         }
   16946     }
   16947 
   16948     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   16949             boolean doingAll, long now) {
   16950         if (mAdjSeq == app.adjSeq) {
   16951             // This adjustment has already been computed.
   16952             return app.curRawAdj;
   16953         }
   16954 
   16955         if (app.thread == null) {
   16956             app.adjSeq = mAdjSeq;
   16957             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16958             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16959             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   16960         }
   16961 
   16962         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   16963         app.adjSource = null;
   16964         app.adjTarget = null;
   16965         app.empty = false;
   16966         app.cached = false;
   16967 
   16968         final int activitiesSize = app.activities.size();
   16969 
   16970         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16971             // The max adjustment doesn't allow this app to be anything
   16972             // below foreground, so it is not worth doing work for it.
   16973             app.adjType = "fixed";
   16974             app.adjSeq = mAdjSeq;
   16975             app.curRawAdj = app.maxAdj;
   16976             app.foregroundActivities = false;
   16977             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   16978             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   16979             // System processes can do UI, and when they do we want to have
   16980             // them trim their memory after the user leaves the UI.  To
   16981             // facilitate this, here we need to determine whether or not it
   16982             // is currently showing UI.
   16983             app.systemNoUi = true;
   16984             if (app == TOP_APP) {
   16985                 app.systemNoUi = false;
   16986             } else if (activitiesSize > 0) {
   16987                 for (int j = 0; j < activitiesSize; j++) {
   16988                     final ActivityRecord r = app.activities.get(j);
   16989                     if (r.visible) {
   16990                         app.systemNoUi = false;
   16991                     }
   16992                 }
   16993             }
   16994             if (!app.systemNoUi) {
   16995                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   16996             }
   16997             return (app.curAdj=app.maxAdj);
   16998         }
   16999 
   17000         app.systemNoUi = false;
   17001 
   17002         // Determine the importance of the process, starting with most
   17003         // important to least, and assign an appropriate OOM adjustment.
   17004         int adj;
   17005         int schedGroup;
   17006         int procState;
   17007         boolean foregroundActivities = false;
   17008         BroadcastQueue queue;
   17009         if (app == TOP_APP) {
   17010             // The last app on the list is the foreground app.
   17011             adj = ProcessList.FOREGROUND_APP_ADJ;
   17012             schedGroup = Process.THREAD_GROUP_DEFAULT;
   17013             app.adjType = "top-activity";
   17014             foregroundActivities = true;
   17015             procState = ActivityManager.PROCESS_STATE_TOP;
   17016         } else if (app.instrumentationClass != null) {
   17017             // Don't want to kill running instrumentation.
   17018             adj = ProcessList.FOREGROUND_APP_ADJ;
   17019             schedGroup = Process.THREAD_GROUP_DEFAULT;
   17020             app.adjType = "instrumentation";
   17021             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17022         } else if ((queue = isReceivingBroadcast(app)) != null) {
   17023             // An app that is currently receiving a broadcast also
   17024             // counts as being in the foreground for OOM killer purposes.
   17025             // It's placed in a sched group based on the nature of the
   17026             // broadcast as reflected by which queue it's active in.
   17027             adj = ProcessList.FOREGROUND_APP_ADJ;
   17028             schedGroup = (queue == mFgBroadcastQueue)
   17029                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17030             app.adjType = "broadcast";
   17031             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   17032         } else if (app.executingServices.size() > 0) {
   17033             // An app that is currently executing a service callback also
   17034             // counts as being in the foreground.
   17035             adj = ProcessList.FOREGROUND_APP_ADJ;
   17036             schedGroup = app.execServicesFg ?
   17037                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17038             app.adjType = "exec-service";
   17039             procState = ActivityManager.PROCESS_STATE_SERVICE;
   17040             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   17041         } else {
   17042             // As far as we know the process is empty.  We may change our mind later.
   17043             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17044             // At this point we don't actually know the adjustment.  Use the cached adj
   17045             // value that the caller wants us to.
   17046             adj = cachedAdj;
   17047             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17048             app.cached = true;
   17049             app.empty = true;
   17050             app.adjType = "cch-empty";
   17051         }
   17052 
   17053         // Examine all activities if not already foreground.
   17054         if (!foregroundActivities && activitiesSize > 0) {
   17055             for (int j = 0; j < activitiesSize; j++) {
   17056                 final ActivityRecord r = app.activities.get(j);
   17057                 if (r.app != app) {
   17058                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   17059                             + app + "?!?");
   17060                     continue;
   17061                 }
   17062                 if (r.visible) {
   17063                     // App has a visible activity; only upgrade adjustment.
   17064                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   17065                         adj = ProcessList.VISIBLE_APP_ADJ;
   17066                         app.adjType = "visible";
   17067                     }
   17068                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   17069                         procState = ActivityManager.PROCESS_STATE_TOP;
   17070                     }
   17071                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17072                     app.cached = false;
   17073                     app.empty = false;
   17074                     foregroundActivities = true;
   17075                     break;
   17076                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   17077                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17078                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17079                         app.adjType = "pausing";
   17080                     }
   17081                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   17082                         procState = ActivityManager.PROCESS_STATE_TOP;
   17083                     }
   17084                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17085                     app.cached = false;
   17086                     app.empty = false;
   17087                     foregroundActivities = true;
   17088                 } else if (r.state == ActivityState.STOPPING) {
   17089                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17090                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17091                         app.adjType = "stopping";
   17092                     }
   17093                     // For the process state, we will at this point consider the
   17094                     // process to be cached.  It will be cached either as an activity
   17095                     // or empty depending on whether the activity is finishing.  We do
   17096                     // this so that we can treat the process as cached for purposes of
   17097                     // memory trimming (determing current memory level, trim command to
   17098                     // send to process) since there can be an arbitrary number of stopping
   17099                     // processes and they should soon all go into the cached state.
   17100                     if (!r.finishing) {
   17101                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   17102                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   17103                         }
   17104                     }
   17105                     app.cached = false;
   17106                     app.empty = false;
   17107                     foregroundActivities = true;
   17108                 } else {
   17109                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17110                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   17111                         app.adjType = "cch-act";
   17112                     }
   17113                 }
   17114             }
   17115         }
   17116 
   17117         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17118             if (app.foregroundServices) {
   17119                 // The user is aware of this app, so make it visible.
   17120                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17121                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17122                 app.cached = false;
   17123                 app.adjType = "fg-service";
   17124                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17125             } else if (app.forcingToForeground != null) {
   17126                 // The user is aware of this app, so make it visible.
   17127                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17128                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17129                 app.cached = false;
   17130                 app.adjType = "force-fg";
   17131                 app.adjSource = app.forcingToForeground;
   17132                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17133             }
   17134         }
   17135 
   17136         if (app == mHeavyWeightProcess) {
   17137             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   17138                 // We don't want to kill the current heavy-weight process.
   17139                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   17140                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17141                 app.cached = false;
   17142                 app.adjType = "heavy";
   17143             }
   17144             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   17145                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   17146             }
   17147         }
   17148 
   17149         if (app == mHomeProcess) {
   17150             if (adj > ProcessList.HOME_APP_ADJ) {
   17151                 // This process is hosting what we currently consider to be the
   17152                 // home app, so we don't want to let it go into the background.
   17153                 adj = ProcessList.HOME_APP_ADJ;
   17154                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17155                 app.cached = false;
   17156                 app.adjType = "home";
   17157             }
   17158             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   17159                 procState = ActivityManager.PROCESS_STATE_HOME;
   17160             }
   17161         }
   17162 
   17163         if (app == mPreviousProcess && app.activities.size() > 0) {
   17164             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   17165                 // This was the previous process that showed UI to the user.
   17166                 // We want to try to keep it around more aggressively, to give
   17167                 // a good experience around switching between two apps.
   17168                 adj = ProcessList.PREVIOUS_APP_ADJ;
   17169                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17170                 app.cached = false;
   17171                 app.adjType = "previous";
   17172             }
   17173             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   17174                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   17175             }
   17176         }
   17177 
   17178         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   17179                 + " reason=" + app.adjType);
   17180 
   17181         // By default, we use the computed adjustment.  It may be changed if
   17182         // there are applications dependent on our services or providers, but
   17183         // this gives us a baseline and makes sure we don't get into an
   17184         // infinite recursion.
   17185         app.adjSeq = mAdjSeq;
   17186         app.curRawAdj = adj;
   17187         app.hasStartedServices = false;
   17188 
   17189         if (mBackupTarget != null && app == mBackupTarget.app) {
   17190             // If possible we want to avoid killing apps while they're being backed up
   17191             if (adj > ProcessList.BACKUP_APP_ADJ) {
   17192                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   17193                 adj = ProcessList.BACKUP_APP_ADJ;
   17194                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   17195                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   17196                 }
   17197                 app.adjType = "backup";
   17198                 app.cached = false;
   17199             }
   17200             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   17201                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   17202             }
   17203         }
   17204 
   17205         boolean mayBeTop = false;
   17206 
   17207         for (int is = app.services.size()-1;
   17208                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17209                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17210                         || procState > ActivityManager.PROCESS_STATE_TOP);
   17211                 is--) {
   17212             ServiceRecord s = app.services.valueAt(is);
   17213             if (s.startRequested) {
   17214                 app.hasStartedServices = true;
   17215                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   17216                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   17217                 }
   17218                 if (app.hasShownUi && app != mHomeProcess) {
   17219                     // If this process has shown some UI, let it immediately
   17220                     // go to the LRU list because it may be pretty heavy with
   17221                     // UI stuff.  We'll tag it with a label just to help
   17222                     // debug and understand what is going on.
   17223                     if (adj > ProcessList.SERVICE_ADJ) {
   17224                         app.adjType = "cch-started-ui-services";
   17225                     }
   17226                 } else {
   17227                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   17228                         // This service has seen some activity within
   17229                         // recent memory, so we will keep its process ahead
   17230                         // of the background processes.
   17231                         if (adj > ProcessList.SERVICE_ADJ) {
   17232                             adj = ProcessList.SERVICE_ADJ;
   17233                             app.adjType = "started-services";
   17234                             app.cached = false;
   17235                         }
   17236                     }
   17237                     // If we have let the service slide into the background
   17238                     // state, still have some text describing what it is doing
   17239                     // even though the service no longer has an impact.
   17240                     if (adj > ProcessList.SERVICE_ADJ) {
   17241                         app.adjType = "cch-started-services";
   17242                     }
   17243                 }
   17244             }
   17245             for (int conni = s.connections.size()-1;
   17246                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17247                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17248                             || procState > ActivityManager.PROCESS_STATE_TOP);
   17249                     conni--) {
   17250                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   17251                 for (int i = 0;
   17252                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   17253                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17254                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   17255                         i++) {
   17256                     // XXX should compute this based on the max of
   17257                     // all connected clients.
   17258                     ConnectionRecord cr = clist.get(i);
   17259                     if (cr.binding.client == app) {
   17260                         // Binding to ourself is not interesting.
   17261                         continue;
   17262                     }
   17263                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   17264                         ProcessRecord client = cr.binding.client;
   17265                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   17266                                 TOP_APP, doingAll, now);
   17267                         int clientProcState = client.curProcState;
   17268                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17269                             // If the other app is cached for any reason, for purposes here
   17270                             // we are going to consider it empty.  The specific cached state
   17271                             // doesn't propagate except under certain conditions.
   17272                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17273                         }
   17274                         String adjType = null;
   17275                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   17276                             // Not doing bind OOM management, so treat
   17277                             // this guy more like a started service.
   17278                             if (app.hasShownUi && app != mHomeProcess) {
   17279                                 // If this process has shown some UI, let it immediately
   17280                                 // go to the LRU list because it may be pretty heavy with
   17281                                 // UI stuff.  We'll tag it with a label just to help
   17282                                 // debug and understand what is going on.
   17283                                 if (adj > clientAdj) {
   17284                                     adjType = "cch-bound-ui-services";
   17285                                 }
   17286                                 app.cached = false;
   17287                                 clientAdj = adj;
   17288                                 clientProcState = procState;
   17289                             } else {
   17290                                 if (now >= (s.lastActivity
   17291                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   17292                                     // This service has not seen activity within
   17293                                     // recent memory, so allow it to drop to the
   17294                                     // LRU list if there is no other reason to keep
   17295                                     // it around.  We'll also tag it with a label just
   17296                                     // to help debug and undertand what is going on.
   17297                                     if (adj > clientAdj) {
   17298                                         adjType = "cch-bound-services";
   17299                                     }
   17300                                     clientAdj = adj;
   17301                                 }
   17302                             }
   17303                         }
   17304                         if (adj > clientAdj) {
   17305                             // If this process has recently shown UI, and
   17306                             // the process that is binding to it is less
   17307                             // important than being visible, then we don't
   17308                             // care about the binding as much as we care
   17309                             // about letting this process get into the LRU
   17310                             // list to be killed and restarted if needed for
   17311                             // memory.
   17312                             if (app.hasShownUi && app != mHomeProcess
   17313                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17314                                 adjType = "cch-bound-ui-services";
   17315                             } else {
   17316                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   17317                                         |Context.BIND_IMPORTANT)) != 0) {
   17318                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   17319                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   17320                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   17321                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   17322                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17323                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17324                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   17325                                     adj = clientAdj;
   17326                                 } else {
   17327                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   17328                                         adj = ProcessList.VISIBLE_APP_ADJ;
   17329                                     }
   17330                                 }
   17331                                 if (!client.cached) {
   17332                                     app.cached = false;
   17333                                 }
   17334                                 adjType = "service";
   17335                             }
   17336                         }
   17337                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   17338                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   17339                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17340                             }
   17341                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   17342                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   17343                                     // Special handling of clients who are in the top state.
   17344                                     // We *may* want to consider this process to be in the
   17345                                     // top state as well, but only if there is not another
   17346                                     // reason for it to be running.  Being on the top is a
   17347                                     // special state, meaning you are specifically running
   17348                                     // for the current top app.  If the process is already
   17349                                     // running in the background for some other reason, it
   17350                                     // is more important to continue considering it to be
   17351                                     // in the background state.
   17352                                     mayBeTop = true;
   17353                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17354                                 } else {
   17355                                     // Special handling for above-top states (persistent
   17356                                     // processes).  These should not bring the current process
   17357                                     // into the top state, since they are not on top.  Instead
   17358                                     // give them the best state after that.
   17359                                     clientProcState =
   17360                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17361                                 }
   17362                             }
   17363                         } else {
   17364                             if (clientProcState <
   17365                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   17366                                 clientProcState =
   17367                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   17368                             }
   17369                         }
   17370                         if (procState > clientProcState) {
   17371                             procState = clientProcState;
   17372                         }
   17373                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   17374                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   17375                             app.pendingUiClean = true;
   17376                         }
   17377                         if (adjType != null) {
   17378                             app.adjType = adjType;
   17379                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17380                                     .REASON_SERVICE_IN_USE;
   17381                             app.adjSource = cr.binding.client;
   17382                             app.adjSourceProcState = clientProcState;
   17383                             app.adjTarget = s.name;
   17384                         }
   17385                     }
   17386                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   17387                         app.treatLikeActivity = true;
   17388                     }
   17389                     final ActivityRecord a = cr.activity;
   17390                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   17391                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   17392                                 (a.visible || a.state == ActivityState.RESUMED
   17393                                  || a.state == ActivityState.PAUSING)) {
   17394                             adj = ProcessList.FOREGROUND_APP_ADJ;
   17395                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   17396                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17397                             }
   17398                             app.cached = false;
   17399                             app.adjType = "service";
   17400                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17401                                     .REASON_SERVICE_IN_USE;
   17402                             app.adjSource = a;
   17403                             app.adjSourceProcState = procState;
   17404                             app.adjTarget = s.name;
   17405                         }
   17406                     }
   17407                 }
   17408             }
   17409         }
   17410 
   17411         for (int provi = app.pubProviders.size()-1;
   17412                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17413                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17414                         || procState > ActivityManager.PROCESS_STATE_TOP);
   17415                 provi--) {
   17416             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   17417             for (int i = cpr.connections.size()-1;
   17418                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17419                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17420                             || procState > ActivityManager.PROCESS_STATE_TOP);
   17421                     i--) {
   17422                 ContentProviderConnection conn = cpr.connections.get(i);
   17423                 ProcessRecord client = conn.client;
   17424                 if (client == app) {
   17425                     // Being our own client is not interesting.
   17426                     continue;
   17427                 }
   17428                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   17429                 int clientProcState = client.curProcState;
   17430                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17431                     // If the other app is cached for any reason, for purposes here
   17432                     // we are going to consider it empty.
   17433                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17434                 }
   17435                 if (adj > clientAdj) {
   17436                     if (app.hasShownUi && app != mHomeProcess
   17437                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17438                         app.adjType = "cch-ui-provider";
   17439                     } else {
   17440                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   17441                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   17442                         app.adjType = "provider";
   17443                     }
   17444                     app.cached &= client.cached;
   17445                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17446                             .REASON_PROVIDER_IN_USE;
   17447                     app.adjSource = client;
   17448                     app.adjSourceProcState = clientProcState;
   17449                     app.adjTarget = cpr.name;
   17450                 }
   17451                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   17452                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   17453                         // Special handling of clients who are in the top state.
   17454                         // We *may* want to consider this process to be in the
   17455                         // top state as well, but only if there is not another
   17456                         // reason for it to be running.  Being on the top is a
   17457                         // special state, meaning you are specifically running
   17458                         // for the current top app.  If the process is already
   17459                         // running in the background for some other reason, it
   17460                         // is more important to continue considering it to be
   17461                         // in the background state.
   17462                         mayBeTop = true;
   17463                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17464                     } else {
   17465                         // Special handling for above-top states (persistent
   17466                         // processes).  These should not bring the current process
   17467                         // into the top state, since they are not on top.  Instead
   17468                         // give them the best state after that.
   17469                         clientProcState =
   17470                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17471                     }
   17472                 }
   17473                 if (procState > clientProcState) {
   17474                     procState = clientProcState;
   17475                 }
   17476                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   17477                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17478                 }
   17479             }
   17480             // If the provider has external (non-framework) process
   17481             // dependencies, ensure that its adjustment is at least
   17482             // FOREGROUND_APP_ADJ.
   17483             if (cpr.hasExternalProcessHandles()) {
   17484                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   17485                     adj = ProcessList.FOREGROUND_APP_ADJ;
   17486                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17487                     app.cached = false;
   17488                     app.adjType = "provider";
   17489                     app.adjTarget = cpr.name;
   17490                 }
   17491                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   17492                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17493                 }
   17494             }
   17495         }
   17496 
   17497         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   17498             // A client of one of our services or providers is in the top state.  We
   17499             // *may* want to be in the top state, but not if we are already running in
   17500             // the background for some other reason.  For the decision here, we are going
   17501             // to pick out a few specific states that we want to remain in when a client
   17502             // is top (states that tend to be longer-term) and otherwise allow it to go
   17503             // to the top state.
   17504             switch (procState) {
   17505                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   17506                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   17507                 case ActivityManager.PROCESS_STATE_SERVICE:
   17508                     // These all are longer-term states, so pull them up to the top
   17509                     // of the background states, but not all the way to the top state.
   17510                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17511                     break;
   17512                 default:
   17513                     // Otherwise, top is a better choice, so take it.
   17514                     procState = ActivityManager.PROCESS_STATE_TOP;
   17515                     break;
   17516             }
   17517         }
   17518 
   17519         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   17520             if (app.hasClientActivities) {
   17521                 // This is a cached process, but with client activities.  Mark it so.
   17522                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   17523                 app.adjType = "cch-client-act";
   17524             } else if (app.treatLikeActivity) {
   17525                 // This is a cached process, but somebody wants us to treat it like it has
   17526                 // an activity, okay!
   17527                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   17528                 app.adjType = "cch-as-act";
   17529             }
   17530         }
   17531 
   17532         if (adj == ProcessList.SERVICE_ADJ) {
   17533             if (doingAll) {
   17534                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   17535                 mNewNumServiceProcs++;
   17536                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   17537                 if (!app.serviceb) {
   17538                     // This service isn't far enough down on the LRU list to
   17539                     // normally be a B service, but if we are low on RAM and it
   17540                     // is large we want to force it down since we would prefer to
   17541                     // keep launcher over it.
   17542                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   17543                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   17544                         app.serviceHighRam = true;
   17545                         app.serviceb = true;
   17546                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   17547                     } else {
   17548                         mNewNumAServiceProcs++;
   17549                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   17550                     }
   17551                 } else {
   17552                     app.serviceHighRam = false;
   17553                 }
   17554             }
   17555             if (app.serviceb) {
   17556                 adj = ProcessList.SERVICE_B_ADJ;
   17557             }
   17558         }
   17559 
   17560         app.curRawAdj = adj;
   17561 
   17562         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   17563         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   17564         if (adj > app.maxAdj) {
   17565             adj = app.maxAdj;
   17566             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   17567                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17568             }
   17569         }
   17570 
   17571         // Do final modification to adj.  Everything we do between here and applying
   17572         // the final setAdj must be done in this function, because we will also use
   17573         // it when computing the final cached adj later.  Note that we don't need to
   17574         // worry about this for max adj above, since max adj will always be used to
   17575         // keep it out of the cached vaues.
   17576         app.curAdj = app.modifyRawOomAdj(adj);
   17577         app.curSchedGroup = schedGroup;
   17578         app.curProcState = procState;
   17579         app.foregroundActivities = foregroundActivities;
   17580 
   17581         return app.curRawAdj;
   17582     }
   17583 
   17584     /**
   17585      * Record new PSS sample for a process.
   17586      */
   17587     void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
   17588         proc.lastPssTime = now;
   17589         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   17590         if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
   17591                 + ": " + pss + " lastPss=" + proc.lastPss
   17592                 + " state=" + ProcessList.makeProcStateString(procState));
   17593         if (proc.initialIdlePss == 0) {
   17594             proc.initialIdlePss = pss;
   17595         }
   17596         proc.lastPss = pss;
   17597         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   17598             proc.lastCachedPss = pss;
   17599         }
   17600     }
   17601 
   17602     /**
   17603      * Schedule PSS collection of a process.
   17604      */
   17605     void requestPssLocked(ProcessRecord proc, int procState) {
   17606         if (mPendingPssProcesses.contains(proc)) {
   17607             return;
   17608         }
   17609         if (mPendingPssProcesses.size() == 0) {
   17610             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17611         }
   17612         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   17613         proc.pssProcState = procState;
   17614         mPendingPssProcesses.add(proc);
   17615     }
   17616 
   17617     /**
   17618      * Schedule PSS collection of all processes.
   17619      */
   17620     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   17621         if (!always) {
   17622             if (now < (mLastFullPssTime +
   17623                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   17624                 return;
   17625             }
   17626         }
   17627         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   17628         mLastFullPssTime = now;
   17629         mFullPssPending = true;
   17630         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   17631         mPendingPssProcesses.clear();
   17632         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   17633             ProcessRecord app = mLruProcesses.get(i);
   17634             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   17635                 app.pssProcState = app.setProcState;
   17636                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17637                         mTestPssMode, isSleeping(), now);
   17638                 mPendingPssProcesses.add(app);
   17639             }
   17640         }
   17641         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17642     }
   17643 
   17644     public void setTestPssMode(boolean enabled) {
   17645         synchronized (this) {
   17646             mTestPssMode = enabled;
   17647             if (enabled) {
   17648                 // Whenever we enable the mode, we want to take a snapshot all of current
   17649                 // process mem use.
   17650                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   17651             }
   17652         }
   17653     }
   17654 
   17655     /**
   17656      * Ask a given process to GC right now.
   17657      */
   17658     final void performAppGcLocked(ProcessRecord app) {
   17659         try {
   17660             app.lastRequestedGc = SystemClock.uptimeMillis();
   17661             if (app.thread != null) {
   17662                 if (app.reportLowMemory) {
   17663                     app.reportLowMemory = false;
   17664                     app.thread.scheduleLowMemory();
   17665                 } else {
   17666                     app.thread.processInBackground();
   17667                 }
   17668             }
   17669         } catch (Exception e) {
   17670             // whatever.
   17671         }
   17672     }
   17673 
   17674     /**
   17675      * Returns true if things are idle enough to perform GCs.
   17676      */
   17677     private final boolean canGcNowLocked() {
   17678         boolean processingBroadcasts = false;
   17679         for (BroadcastQueue q : mBroadcastQueues) {
   17680             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   17681                 processingBroadcasts = true;
   17682             }
   17683         }
   17684         return !processingBroadcasts
   17685                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
   17686     }
   17687 
   17688     /**
   17689      * Perform GCs on all processes that are waiting for it, but only
   17690      * if things are idle.
   17691      */
   17692     final void performAppGcsLocked() {
   17693         final int N = mProcessesToGc.size();
   17694         if (N <= 0) {
   17695             return;
   17696         }
   17697         if (canGcNowLocked()) {
   17698             while (mProcessesToGc.size() > 0) {
   17699                 ProcessRecord proc = mProcessesToGc.remove(0);
   17700                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   17701                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   17702                             <= SystemClock.uptimeMillis()) {
   17703                         // To avoid spamming the system, we will GC processes one
   17704                         // at a time, waiting a few seconds between each.
   17705                         performAppGcLocked(proc);
   17706                         scheduleAppGcsLocked();
   17707                         return;
   17708                     } else {
   17709                         // It hasn't been long enough since we last GCed this
   17710                         // process...  put it in the list to wait for its time.
   17711                         addProcessToGcListLocked(proc);
   17712                         break;
   17713                     }
   17714                 }
   17715             }
   17716 
   17717             scheduleAppGcsLocked();
   17718         }
   17719     }
   17720 
   17721     /**
   17722      * If all looks good, perform GCs on all processes waiting for them.
   17723      */
   17724     final void performAppGcsIfAppropriateLocked() {
   17725         if (canGcNowLocked()) {
   17726             performAppGcsLocked();
   17727             return;
   17728         }
   17729         // Still not idle, wait some more.
   17730         scheduleAppGcsLocked();
   17731     }
   17732 
   17733     /**
   17734      * Schedule the execution of all pending app GCs.
   17735      */
   17736     final void scheduleAppGcsLocked() {
   17737         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   17738 
   17739         if (mProcessesToGc.size() > 0) {
   17740             // Schedule a GC for the time to the next process.
   17741             ProcessRecord proc = mProcessesToGc.get(0);
   17742             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   17743 
   17744             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   17745             long now = SystemClock.uptimeMillis();
   17746             if (when < (now+GC_TIMEOUT)) {
   17747                 when = now + GC_TIMEOUT;
   17748             }
   17749             mHandler.sendMessageAtTime(msg, when);
   17750         }
   17751     }
   17752 
   17753     /**
   17754      * Add a process to the array of processes waiting to be GCed.  Keeps the
   17755      * list in sorted order by the last GC time.  The process can't already be
   17756      * on the list.
   17757      */
   17758     final void addProcessToGcListLocked(ProcessRecord proc) {
   17759         boolean added = false;
   17760         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   17761             if (mProcessesToGc.get(i).lastRequestedGc <
   17762                     proc.lastRequestedGc) {
   17763                 added = true;
   17764                 mProcessesToGc.add(i+1, proc);
   17765                 break;
   17766             }
   17767         }
   17768         if (!added) {
   17769             mProcessesToGc.add(0, proc);
   17770         }
   17771     }
   17772 
   17773     /**
   17774      * Set up to ask a process to GC itself.  This will either do it
   17775      * immediately, or put it on the list of processes to gc the next
   17776      * time things are idle.
   17777      */
   17778     final void scheduleAppGcLocked(ProcessRecord app) {
   17779         long now = SystemClock.uptimeMillis();
   17780         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   17781             return;
   17782         }
   17783         if (!mProcessesToGc.contains(app)) {
   17784             addProcessToGcListLocked(app);
   17785             scheduleAppGcsLocked();
   17786         }
   17787     }
   17788 
   17789     final void checkExcessivePowerUsageLocked(boolean doKills) {
   17790         updateCpuStatsNow();
   17791 
   17792         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17793         boolean doWakeKills = doKills;
   17794         boolean doCpuKills = doKills;
   17795         if (mLastPowerCheckRealtime == 0) {
   17796             doWakeKills = false;
   17797         }
   17798         if (mLastPowerCheckUptime == 0) {
   17799             doCpuKills = false;
   17800         }
   17801         if (stats.isScreenOn()) {
   17802             doWakeKills = false;
   17803         }
   17804         final long curRealtime = SystemClock.elapsedRealtime();
   17805         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   17806         final long curUptime = SystemClock.uptimeMillis();
   17807         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   17808         mLastPowerCheckRealtime = curRealtime;
   17809         mLastPowerCheckUptime = curUptime;
   17810         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   17811             doWakeKills = false;
   17812         }
   17813         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   17814             doCpuKills = false;
   17815         }
   17816         int i = mLruProcesses.size();
   17817         while (i > 0) {
   17818             i--;
   17819             ProcessRecord app = mLruProcesses.get(i);
   17820             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   17821                 long wtime;
   17822                 synchronized (stats) {
   17823                     wtime = stats.getProcessWakeTime(app.info.uid,
   17824                             app.pid, curRealtime);
   17825                 }
   17826                 long wtimeUsed = wtime - app.lastWakeTime;
   17827                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   17828                 if (DEBUG_POWER) {
   17829                     StringBuilder sb = new StringBuilder(128);
   17830                     sb.append("Wake for ");
   17831                     app.toShortString(sb);
   17832                     sb.append(": over ");
   17833                     TimeUtils.formatDuration(realtimeSince, sb);
   17834                     sb.append(" used ");
   17835                     TimeUtils.formatDuration(wtimeUsed, sb);
   17836                     sb.append(" (");
   17837                     sb.append((wtimeUsed*100)/realtimeSince);
   17838                     sb.append("%)");
   17839                     Slog.i(TAG, sb.toString());
   17840                     sb.setLength(0);
   17841                     sb.append("CPU for ");
   17842                     app.toShortString(sb);
   17843                     sb.append(": over ");
   17844                     TimeUtils.formatDuration(uptimeSince, sb);
   17845                     sb.append(" used ");
   17846                     TimeUtils.formatDuration(cputimeUsed, sb);
   17847                     sb.append(" (");
   17848                     sb.append((cputimeUsed*100)/uptimeSince);
   17849                     sb.append("%)");
   17850                     Slog.i(TAG, sb.toString());
   17851                 }
   17852                 // If a process has held a wake lock for more
   17853                 // than 50% of the time during this period,
   17854                 // that sounds bad.  Kill!
   17855                 if (doWakeKills && realtimeSince > 0
   17856                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   17857                     synchronized (stats) {
   17858                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   17859                                 realtimeSince, wtimeUsed);
   17860                     }
   17861                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   17862                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   17863                 } else if (doCpuKills && uptimeSince > 0
   17864                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   17865                     synchronized (stats) {
   17866                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   17867                                 uptimeSince, cputimeUsed);
   17868                     }
   17869                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   17870                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   17871                 } else {
   17872                     app.lastWakeTime = wtime;
   17873                     app.lastCpuTime = app.curCpuTime;
   17874                 }
   17875             }
   17876         }
   17877     }
   17878 
   17879     private final boolean applyOomAdjLocked(ProcessRecord app,
   17880             ProcessRecord TOP_APP, boolean doingAll, long now) {
   17881         boolean success = true;
   17882 
   17883         if (app.curRawAdj != app.setRawAdj) {
   17884             app.setRawAdj = app.curRawAdj;
   17885         }
   17886 
   17887         int changes = 0;
   17888 
   17889         if (app.curAdj != app.setAdj) {
   17890             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   17891             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   17892                 TAG, "Set " + app.pid + " " + app.processName +
   17893                 " adj " + app.curAdj + ": " + app.adjType);
   17894             app.setAdj = app.curAdj;
   17895         }
   17896 
   17897         if (app.setSchedGroup != app.curSchedGroup) {
   17898             app.setSchedGroup = app.curSchedGroup;
   17899             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17900                     "Setting process group of " + app.processName
   17901                     + " to " + app.curSchedGroup);
   17902             if (app.waitingToKill != null &&
   17903                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   17904                 app.kill(app.waitingToKill, true);
   17905                 success = false;
   17906             } else {
   17907                 if (true) {
   17908                     long oldId = Binder.clearCallingIdentity();
   17909                     try {
   17910                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   17911                     } catch (Exception e) {
   17912                         Slog.w(TAG, "Failed setting process group of " + app.pid
   17913                                 + " to " + app.curSchedGroup);
   17914                         e.printStackTrace();
   17915                     } finally {
   17916                         Binder.restoreCallingIdentity(oldId);
   17917                     }
   17918                 } else {
   17919                     if (app.thread != null) {
   17920                         try {
   17921                             app.thread.setSchedulingGroup(app.curSchedGroup);
   17922                         } catch (RemoteException e) {
   17923                         }
   17924                     }
   17925                 }
   17926                 Process.setSwappiness(app.pid,
   17927                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   17928             }
   17929         }
   17930         if (app.repForegroundActivities != app.foregroundActivities) {
   17931             app.repForegroundActivities = app.foregroundActivities;
   17932             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   17933         }
   17934         if (app.repProcState != app.curProcState) {
   17935             app.repProcState = app.curProcState;
   17936             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   17937             if (app.thread != null) {
   17938                 try {
   17939                     if (false) {
   17940                         //RuntimeException h = new RuntimeException("here");
   17941                         Slog.i(TAG, "Sending new process state " + app.repProcState
   17942                                 + " to " + app /*, h*/);
   17943                     }
   17944                     app.thread.setProcessState(app.repProcState);
   17945                 } catch (RemoteException e) {
   17946                 }
   17947             }
   17948         }
   17949         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   17950                 app.setProcState)) {
   17951             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   17952                 // Experimental code to more aggressively collect pss while
   17953                 // running test...  the problem is that this tends to collect
   17954                 // the data right when a process is transitioning between process
   17955                 // states, which well tend to give noisy data.
   17956                 long start = SystemClock.uptimeMillis();
   17957                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   17958                 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
   17959                 mPendingPssProcesses.remove(app);
   17960                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   17961                         + " to " + app.curProcState + ": "
   17962                         + (SystemClock.uptimeMillis()-start) + "ms");
   17963             }
   17964             app.lastStateTime = now;
   17965             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17966                     mTestPssMode, isSleeping(), now);
   17967             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   17968                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   17969                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   17970                     + (app.nextPssTime-now) + ": " + app);
   17971         } else {
   17972             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   17973                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   17974                     mTestPssMode)))) {
   17975                 requestPssLocked(app, app.setProcState);
   17976                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   17977                         mTestPssMode, isSleeping(), now);
   17978             } else if (false && DEBUG_PSS) {
   17979                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   17980             }
   17981         }
   17982         if (app.setProcState != app.curProcState) {
   17983             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17984                     "Proc state change of " + app.processName
   17985                     + " to " + app.curProcState);
   17986             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17987             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17988             if (setImportant && !curImportant) {
   17989                 // This app is no longer something we consider important enough to allow to
   17990                 // use arbitrary amounts of battery power.  Note
   17991                 // its current wake lock time to later know to kill it if
   17992                 // it is not behaving well.
   17993                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17994                 synchronized (stats) {
   17995                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   17996                             app.pid, SystemClock.elapsedRealtime());
   17997                 }
   17998                 app.lastCpuTime = app.curCpuTime;
   17999 
   18000             }
   18001             app.setProcState = app.curProcState;
   18002             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   18003                 app.notCachedSinceIdle = false;
   18004             }
   18005             if (!doingAll) {
   18006                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   18007             } else {
   18008                 app.procStateChanged = true;
   18009             }
   18010         }
   18011 
   18012         if (changes != 0) {
   18013             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   18014             int i = mPendingProcessChanges.size()-1;
   18015             ProcessChangeItem item = null;
   18016             while (i >= 0) {
   18017                 item = mPendingProcessChanges.get(i);
   18018                 if (item.pid == app.pid) {
   18019                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   18020                     break;
   18021                 }
   18022                 i--;
   18023             }
   18024             if (i < 0) {
   18025                 // No existing item in pending changes; need a new one.
   18026                 final int NA = mAvailProcessChanges.size();
   18027                 if (NA > 0) {
   18028                     item = mAvailProcessChanges.remove(NA-1);
   18029                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   18030                 } else {
   18031                     item = new ProcessChangeItem();
   18032                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   18033                 }
   18034                 item.changes = 0;
   18035                 item.pid = app.pid;
   18036                 item.uid = app.info.uid;
   18037                 if (mPendingProcessChanges.size() == 0) {
   18038                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   18039                             "*** Enqueueing dispatch processes changed!");
   18040                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   18041                 }
   18042                 mPendingProcessChanges.add(item);
   18043             }
   18044             item.changes |= changes;
   18045             item.processState = app.repProcState;
   18046             item.foregroundActivities = app.repForegroundActivities;
   18047             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   18048                     + Integer.toHexString(System.identityHashCode(item))
   18049                     + " " + app.toShortString() + ": changes=" + item.changes
   18050                     + " procState=" + item.processState
   18051                     + " foreground=" + item.foregroundActivities
   18052                     + " type=" + app.adjType + " source=" + app.adjSource
   18053                     + " target=" + app.adjTarget);
   18054         }
   18055 
   18056         return success;
   18057     }
   18058 
   18059     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   18060         if (proc.thread != null) {
   18061             if (proc.baseProcessTracker != null) {
   18062                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   18063             }
   18064             if (proc.repProcState >= 0) {
   18065                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
   18066                         proc.repProcState);
   18067             }
   18068         }
   18069     }
   18070 
   18071     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   18072             ProcessRecord TOP_APP, boolean doingAll, long now) {
   18073         if (app.thread == null) {
   18074             return false;
   18075         }
   18076 
   18077         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   18078 
   18079         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
   18080     }
   18081 
   18082     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   18083             boolean oomAdj) {
   18084         if (isForeground != proc.foregroundServices) {
   18085             proc.foregroundServices = isForeground;
   18086             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   18087                     proc.info.uid);
   18088             if (isForeground) {
   18089                 if (curProcs == null) {
   18090                     curProcs = new ArrayList<ProcessRecord>();
   18091                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   18092                 }
   18093                 if (!curProcs.contains(proc)) {
   18094                     curProcs.add(proc);
   18095                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   18096                             proc.info.packageName, proc.info.uid);
   18097                 }
   18098             } else {
   18099                 if (curProcs != null) {
   18100                     if (curProcs.remove(proc)) {
   18101                         mBatteryStatsService.noteEvent(
   18102                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   18103                                 proc.info.packageName, proc.info.uid);
   18104                         if (curProcs.size() <= 0) {
   18105                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   18106                         }
   18107                     }
   18108                 }
   18109             }
   18110             if (oomAdj) {
   18111                 updateOomAdjLocked();
   18112             }
   18113         }
   18114     }
   18115 
   18116     private final ActivityRecord resumedAppLocked() {
   18117         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   18118         String pkg;
   18119         int uid;
   18120         if (act != null) {
   18121             pkg = act.packageName;
   18122             uid = act.info.applicationInfo.uid;
   18123         } else {
   18124             pkg = null;
   18125             uid = -1;
   18126         }
   18127         // Has the UID or resumed package name changed?
   18128         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   18129                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   18130             if (mCurResumedPackage != null) {
   18131                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   18132                         mCurResumedPackage, mCurResumedUid);
   18133             }
   18134             mCurResumedPackage = pkg;
   18135             mCurResumedUid = uid;
   18136             if (mCurResumedPackage != null) {
   18137                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   18138                         mCurResumedPackage, mCurResumedUid);
   18139             }
   18140         }
   18141         return act;
   18142     }
   18143 
   18144     final boolean updateOomAdjLocked(ProcessRecord app) {
   18145         final ActivityRecord TOP_ACT = resumedAppLocked();
   18146         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   18147         final boolean wasCached = app.cached;
   18148 
   18149         mAdjSeq++;
   18150 
   18151         // This is the desired cached adjusment we want to tell it to use.
   18152         // If our app is currently cached, we know it, and that is it.  Otherwise,
   18153         // we don't know it yet, and it needs to now be cached we will then
   18154         // need to do a complete oom adj.
   18155         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   18156                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   18157         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   18158                 SystemClock.uptimeMillis());
   18159         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   18160             // Changed to/from cached state, so apps after it in the LRU
   18161             // list may also be changed.
   18162             updateOomAdjLocked();
   18163         }
   18164         return success;
   18165     }
   18166 
   18167     final void updateOomAdjLocked() {
   18168         final ActivityRecord TOP_ACT = resumedAppLocked();
   18169         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   18170         final long now = SystemClock.uptimeMillis();
   18171         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   18172         final int N = mLruProcesses.size();
   18173 
   18174         if (false) {
   18175             RuntimeException e = new RuntimeException();
   18176             e.fillInStackTrace();
   18177             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   18178         }
   18179 
   18180         mAdjSeq++;
   18181         mNewNumServiceProcs = 0;
   18182         mNewNumAServiceProcs = 0;
   18183 
   18184         final int emptyProcessLimit;
   18185         final int cachedProcessLimit;
   18186         if (mProcessLimit <= 0) {
   18187             emptyProcessLimit = cachedProcessLimit = 0;
   18188         } else if (mProcessLimit == 1) {
   18189             emptyProcessLimit = 1;
   18190             cachedProcessLimit = 0;
   18191         } else {
   18192             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   18193             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   18194         }
   18195 
   18196         // Let's determine how many processes we have running vs.
   18197         // how many slots we have for background processes; we may want
   18198         // to put multiple processes in a slot of there are enough of
   18199         // them.
   18200         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   18201                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   18202         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   18203         if (numEmptyProcs > cachedProcessLimit) {
   18204             // If there are more empty processes than our limit on cached
   18205             // processes, then use the cached process limit for the factor.
   18206             // This ensures that the really old empty processes get pushed
   18207             // down to the bottom, so if we are running low on memory we will
   18208             // have a better chance at keeping around more cached processes
   18209             // instead of a gazillion empty processes.
   18210             numEmptyProcs = cachedProcessLimit;
   18211         }
   18212         int emptyFactor = numEmptyProcs/numSlots;
   18213         if (emptyFactor < 1) emptyFactor = 1;
   18214         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   18215         if (cachedFactor < 1) cachedFactor = 1;
   18216         int stepCached = 0;
   18217         int stepEmpty = 0;
   18218         int numCached = 0;
   18219         int numEmpty = 0;
   18220         int numTrimming = 0;
   18221 
   18222         mNumNonCachedProcs = 0;
   18223         mNumCachedHiddenProcs = 0;
   18224 
   18225         // First update the OOM adjustment for each of the
   18226         // application processes based on their current state.
   18227         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   18228         int nextCachedAdj = curCachedAdj+1;
   18229         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   18230         int nextEmptyAdj = curEmptyAdj+2;
   18231         for (int i=N-1; i>=0; i--) {
   18232             ProcessRecord app = mLruProcesses.get(i);
   18233             if (!app.killedByAm && app.thread != null) {
   18234                 app.procStateChanged = false;
   18235                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   18236 
   18237                 // If we haven't yet assigned the final cached adj
   18238                 // to the process, do that now.
   18239                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   18240                     switch (app.curProcState) {
   18241                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   18242                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   18243                             // This process is a cached process holding activities...
   18244                             // assign it the next cached value for that type, and then
   18245                             // step that cached level.
   18246                             app.curRawAdj = curCachedAdj;
   18247                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   18248                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
   18249                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   18250                                     + ")");
   18251                             if (curCachedAdj != nextCachedAdj) {
   18252                                 stepCached++;
   18253                                 if (stepCached >= cachedFactor) {
   18254                                     stepCached = 0;
   18255                                     curCachedAdj = nextCachedAdj;
   18256                                     nextCachedAdj += 2;
   18257                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   18258                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   18259                                     }
   18260                                 }
   18261                             }
   18262                             break;
   18263                         default:
   18264                             // For everything else, assign next empty cached process
   18265                             // level and bump that up.  Note that this means that
   18266                             // long-running services that have dropped down to the
   18267                             // cached level will be treated as empty (since their process
   18268                             // state is still as a service), which is what we want.
   18269                             app.curRawAdj = curEmptyAdj;
   18270                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   18271                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
   18272                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   18273                                     + ")");
   18274                             if (curEmptyAdj != nextEmptyAdj) {
   18275                                 stepEmpty++;
   18276                                 if (stepEmpty >= emptyFactor) {
   18277                                     stepEmpty = 0;
   18278                                     curEmptyAdj = nextEmptyAdj;
   18279                                     nextEmptyAdj += 2;
   18280                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   18281                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   18282                                     }
   18283                                 }
   18284                             }
   18285                             break;
   18286                     }
   18287                 }
   18288 
   18289                 applyOomAdjLocked(app, TOP_APP, true, now);
   18290 
   18291                 // Count the number of process types.
   18292                 switch (app.curProcState) {
   18293                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   18294                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   18295                         mNumCachedHiddenProcs++;
   18296                         numCached++;
   18297                         if (numCached > cachedProcessLimit) {
   18298                             app.kill("cached #" + numCached, true);
   18299                         }
   18300                         break;
   18301                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   18302                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   18303                                 && app.lastActivityTime < oldTime) {
   18304                             app.kill("empty for "
   18305                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   18306                                     / 1000) + "s", true);
   18307                         } else {
   18308                             numEmpty++;
   18309                             if (numEmpty > emptyProcessLimit) {
   18310                                 app.kill("empty #" + numEmpty, true);
   18311                             }
   18312                         }
   18313                         break;
   18314                     default:
   18315                         mNumNonCachedProcs++;
   18316                         break;
   18317                 }
   18318 
   18319                 if (app.isolated && app.services.size() <= 0) {
   18320                     // If this is an isolated process, and there are no
   18321                     // services running in it, then the process is no longer
   18322                     // needed.  We agressively kill these because we can by
   18323                     // definition not re-use the same process again, and it is
   18324                     // good to avoid having whatever code was running in them
   18325                     // left sitting around after no longer needed.
   18326                     app.kill("isolated not needed", true);
   18327                 }
   18328 
   18329                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   18330                         && !app.killedByAm) {
   18331                     numTrimming++;
   18332                 }
   18333             }
   18334         }
   18335 
   18336         mNumServiceProcs = mNewNumServiceProcs;
   18337 
   18338         // Now determine the memory trimming level of background processes.
   18339         // Unfortunately we need to start at the back of the list to do this
   18340         // properly.  We only do this if the number of background apps we
   18341         // are managing to keep around is less than half the maximum we desire;
   18342         // if we are keeping a good number around, we'll let them use whatever
   18343         // memory they want.
   18344         final int numCachedAndEmpty = numCached + numEmpty;
   18345         int memFactor;
   18346         if (numCached <= ProcessList.TRIM_CACHED_APPS
   18347                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   18348             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   18349                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   18350             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   18351                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   18352             } else {
   18353                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   18354             }
   18355         } else {
   18356             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   18357         }
   18358         // We always allow the memory level to go up (better).  We only allow it to go
   18359         // down if we are in a state where that is allowed, *and* the total number of processes
   18360         // has gone down since last time.
   18361         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   18362                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   18363                 + " last=" + mLastNumProcesses);
   18364         if (memFactor > mLastMemoryLevel) {
   18365             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   18366                 memFactor = mLastMemoryLevel;
   18367                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   18368             }
   18369         }
   18370         mLastMemoryLevel = memFactor;
   18371         mLastNumProcesses = mLruProcesses.size();
   18372         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
   18373         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   18374         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   18375             if (mLowRamStartTime == 0) {
   18376                 mLowRamStartTime = now;
   18377             }
   18378             int step = 0;
   18379             int fgTrimLevel;
   18380             switch (memFactor) {
   18381                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   18382                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   18383                     break;
   18384                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   18385                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   18386                     break;
   18387                 default:
   18388                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   18389                     break;
   18390             }
   18391             int factor = numTrimming/3;
   18392             int minFactor = 2;
   18393             if (mHomeProcess != null) minFactor++;
   18394             if (mPreviousProcess != null) minFactor++;
   18395             if (factor < minFactor) factor = minFactor;
   18396             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   18397             for (int i=N-1; i>=0; i--) {
   18398                 ProcessRecord app = mLruProcesses.get(i);
   18399                 if (allChanged || app.procStateChanged) {
   18400                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   18401                     app.procStateChanged = false;
   18402                 }
   18403                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   18404                         && !app.killedByAm) {
   18405                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   18406                         try {
   18407                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18408                                     "Trimming memory of " + app.processName
   18409                                     + " to " + curLevel);
   18410                             app.thread.scheduleTrimMemory(curLevel);
   18411                         } catch (RemoteException e) {
   18412                         }
   18413                         if (false) {
   18414                             // For now we won't do this; our memory trimming seems
   18415                             // to be good enough at this point that destroying
   18416                             // activities causes more harm than good.
   18417                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   18418                                     && app != mHomeProcess && app != mPreviousProcess) {
   18419                                 // Need to do this on its own message because the stack may not
   18420                                 // be in a consistent state at this point.
   18421                                 // For these apps we will also finish their activities
   18422                                 // to help them free memory.
   18423                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   18424                             }
   18425                         }
   18426                     }
   18427                     app.trimMemoryLevel = curLevel;
   18428                     step++;
   18429                     if (step >= factor) {
   18430                         step = 0;
   18431                         switch (curLevel) {
   18432                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   18433                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   18434                                 break;
   18435                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   18436                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   18437                                 break;
   18438                         }
   18439                     }
   18440                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   18441                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   18442                             && app.thread != null) {
   18443                         try {
   18444                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18445                                     "Trimming memory of heavy-weight " + app.processName
   18446                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   18447                             app.thread.scheduleTrimMemory(
   18448                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   18449                         } catch (RemoteException e) {
   18450                         }
   18451                     }
   18452                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   18453                 } else {
   18454                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   18455                             || app.systemNoUi) && app.pendingUiClean) {
   18456                         // If this application is now in the background and it
   18457                         // had done UI, then give it the special trim level to
   18458                         // have it free UI resources.
   18459                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   18460                         if (app.trimMemoryLevel < level && app.thread != null) {
   18461                             try {
   18462                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18463                                         "Trimming memory of bg-ui " + app.processName
   18464                                         + " to " + level);
   18465                                 app.thread.scheduleTrimMemory(level);
   18466                             } catch (RemoteException e) {
   18467                             }
   18468                         }
   18469                         app.pendingUiClean = false;
   18470                     }
   18471                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   18472                         try {
   18473                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18474                                     "Trimming memory of fg " + app.processName
   18475                                     + " to " + fgTrimLevel);
   18476                             app.thread.scheduleTrimMemory(fgTrimLevel);
   18477                         } catch (RemoteException e) {
   18478                         }
   18479                     }
   18480                     app.trimMemoryLevel = fgTrimLevel;
   18481                 }
   18482             }
   18483         } else {
   18484             if (mLowRamStartTime != 0) {
   18485                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   18486                 mLowRamStartTime = 0;
   18487             }
   18488             for (int i=N-1; i>=0; i--) {
   18489                 ProcessRecord app = mLruProcesses.get(i);
   18490                 if (allChanged || app.procStateChanged) {
   18491                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   18492                     app.procStateChanged = false;
   18493                 }
   18494                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   18495                         || app.systemNoUi) && app.pendingUiClean) {
   18496                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   18497                             && app.thread != null) {
   18498                         try {
   18499                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18500                                     "Trimming memory of ui hidden " + app.processName
   18501                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   18502                             app.thread.scheduleTrimMemory(
   18503                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   18504                         } catch (RemoteException e) {
   18505                         }
   18506                     }
   18507                     app.pendingUiClean = false;
   18508                 }
   18509                 app.trimMemoryLevel = 0;
   18510             }
   18511         }
   18512 
   18513         if (mAlwaysFinishActivities) {
   18514             // Need to do this on its own message because the stack may not
   18515             // be in a consistent state at this point.
   18516             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   18517         }
   18518 
   18519         if (allChanged) {
   18520             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   18521         }
   18522 
   18523         if (mProcessStats.shouldWriteNowLocked(now)) {
   18524             mHandler.post(new Runnable() {
   18525                 @Override public void run() {
   18526                     synchronized (ActivityManagerService.this) {
   18527                         mProcessStats.writeStateAsyncLocked();
   18528                     }
   18529                 }
   18530             });
   18531         }
   18532 
   18533         if (DEBUG_OOM_ADJ) {
   18534             if (false) {
   18535                 RuntimeException here = new RuntimeException("here");
   18536                 here.fillInStackTrace();
   18537                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
   18538             } else {
   18539                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   18540             }
   18541         }
   18542     }
   18543 
   18544     final void trimApplications() {
   18545         synchronized (this) {
   18546             int i;
   18547 
   18548             // First remove any unused application processes whose package
   18549             // has been removed.
   18550             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   18551                 final ProcessRecord app = mRemovedProcesses.get(i);
   18552                 if (app.activities.size() == 0
   18553                         && app.curReceiver == null && app.services.size() == 0) {
   18554                     Slog.i(
   18555                         TAG, "Exiting empty application process "
   18556                         + app.processName + " ("
   18557                         + (app.thread != null ? app.thread.asBinder() : null)
   18558                         + ")\n");
   18559                     if (app.pid > 0 && app.pid != MY_PID) {
   18560                         app.kill("empty", false);
   18561                     } else {
   18562                         try {
   18563                             app.thread.scheduleExit();
   18564                         } catch (Exception e) {
   18565                             // Ignore exceptions.
   18566                         }
   18567                     }
   18568                     cleanUpApplicationRecordLocked(app, false, true, -1);
   18569                     mRemovedProcesses.remove(i);
   18570 
   18571                     if (app.persistent) {
   18572                         addAppLocked(app.info, false, null /* ABI override */);
   18573                     }
   18574                 }
   18575             }
   18576 
   18577             // Now update the oom adj for all processes.
   18578             updateOomAdjLocked();
   18579         }
   18580     }
   18581 
   18582     /** This method sends the specified signal to each of the persistent apps */
   18583     public void signalPersistentProcesses(int sig) throws RemoteException {
   18584         if (sig != Process.SIGNAL_USR1) {
   18585             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   18586         }
   18587 
   18588         synchronized (this) {
   18589             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   18590                     != PackageManager.PERMISSION_GRANTED) {
   18591                 throw new SecurityException("Requires permission "
   18592                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   18593             }
   18594 
   18595             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   18596                 ProcessRecord r = mLruProcesses.get(i);
   18597                 if (r.thread != null && r.persistent) {
   18598                     Process.sendSignal(r.pid, sig);
   18599                 }
   18600             }
   18601         }
   18602     }
   18603 
   18604     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   18605         if (proc == null || proc == mProfileProc) {
   18606             proc = mProfileProc;
   18607             profileType = mProfileType;
   18608             clearProfilerLocked();
   18609         }
   18610         if (proc == null) {
   18611             return;
   18612         }
   18613         try {
   18614             proc.thread.profilerControl(false, null, profileType);
   18615         } catch (RemoteException e) {
   18616             throw new IllegalStateException("Process disappeared");
   18617         }
   18618     }
   18619 
   18620     private void clearProfilerLocked() {
   18621         if (mProfileFd != null) {
   18622             try {
   18623                 mProfileFd.close();
   18624             } catch (IOException e) {
   18625             }
   18626         }
   18627         mProfileApp = null;
   18628         mProfileProc = null;
   18629         mProfileFile = null;
   18630         mProfileType = 0;
   18631         mAutoStopProfiler = false;
   18632         mSamplingInterval = 0;
   18633     }
   18634 
   18635     public boolean profileControl(String process, int userId, boolean start,
   18636             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   18637 
   18638         try {
   18639             synchronized (this) {
   18640                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18641                 // its own permission.
   18642                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18643                         != PackageManager.PERMISSION_GRANTED) {
   18644                     throw new SecurityException("Requires permission "
   18645                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18646                 }
   18647 
   18648                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   18649                     throw new IllegalArgumentException("null profile info or fd");
   18650                 }
   18651 
   18652                 ProcessRecord proc = null;
   18653                 if (process != null) {
   18654                     proc = findProcessLocked(process, userId, "profileControl");
   18655                 }
   18656 
   18657                 if (start && (proc == null || proc.thread == null)) {
   18658                     throw new IllegalArgumentException("Unknown process: " + process);
   18659                 }
   18660 
   18661                 if (start) {
   18662                     stopProfilerLocked(null, 0);
   18663                     setProfileApp(proc.info, proc.processName, profilerInfo);
   18664                     mProfileProc = proc;
   18665                     mProfileType = profileType;
   18666                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   18667                     try {
   18668                         fd = fd.dup();
   18669                     } catch (IOException e) {
   18670                         fd = null;
   18671                     }
   18672                     profilerInfo.profileFd = fd;
   18673                     proc.thread.profilerControl(start, profilerInfo, profileType);
   18674                     fd = null;
   18675                     mProfileFd = null;
   18676                 } else {
   18677                     stopProfilerLocked(proc, profileType);
   18678                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   18679                         try {
   18680                             profilerInfo.profileFd.close();
   18681                         } catch (IOException e) {
   18682                         }
   18683                     }
   18684                 }
   18685 
   18686                 return true;
   18687             }
   18688         } catch (RemoteException e) {
   18689             throw new IllegalStateException("Process disappeared");
   18690         } finally {
   18691             if (profilerInfo != null && profilerInfo.profileFd != null) {
   18692                 try {
   18693                     profilerInfo.profileFd.close();
   18694                 } catch (IOException e) {
   18695                 }
   18696             }
   18697         }
   18698     }
   18699 
   18700     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   18701         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18702                 userId, true, ALLOW_FULL_ONLY, callName, null);
   18703         ProcessRecord proc = null;
   18704         try {
   18705             int pid = Integer.parseInt(process);
   18706             synchronized (mPidsSelfLocked) {
   18707                 proc = mPidsSelfLocked.get(pid);
   18708             }
   18709         } catch (NumberFormatException e) {
   18710         }
   18711 
   18712         if (proc == null) {
   18713             ArrayMap<String, SparseArray<ProcessRecord>> all
   18714                     = mProcessNames.getMap();
   18715             SparseArray<ProcessRecord> procs = all.get(process);
   18716             if (procs != null && procs.size() > 0) {
   18717                 proc = procs.valueAt(0);
   18718                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   18719                     for (int i=1; i<procs.size(); i++) {
   18720                         ProcessRecord thisProc = procs.valueAt(i);
   18721                         if (thisProc.userId == userId) {
   18722                             proc = thisProc;
   18723                             break;
   18724                         }
   18725                     }
   18726                 }
   18727             }
   18728         }
   18729 
   18730         return proc;
   18731     }
   18732 
   18733     public boolean dumpHeap(String process, int userId, boolean managed,
   18734             String path, ParcelFileDescriptor fd) throws RemoteException {
   18735 
   18736         try {
   18737             synchronized (this) {
   18738                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18739                 // its own permission (same as profileControl).
   18740                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18741                         != PackageManager.PERMISSION_GRANTED) {
   18742                     throw new SecurityException("Requires permission "
   18743                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18744                 }
   18745 
   18746                 if (fd == null) {
   18747                     throw new IllegalArgumentException("null fd");
   18748                 }
   18749 
   18750                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   18751                 if (proc == null || proc.thread == null) {
   18752                     throw new IllegalArgumentException("Unknown process: " + process);
   18753                 }
   18754 
   18755                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   18756                 if (!isDebuggable) {
   18757                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   18758                         throw new SecurityException("Process not debuggable: " + proc);
   18759                     }
   18760                 }
   18761 
   18762                 proc.thread.dumpHeap(managed, path, fd);
   18763                 fd = null;
   18764                 return true;
   18765             }
   18766         } catch (RemoteException e) {
   18767             throw new IllegalStateException("Process disappeared");
   18768         } finally {
   18769             if (fd != null) {
   18770                 try {
   18771                     fd.close();
   18772                 } catch (IOException e) {
   18773                 }
   18774             }
   18775         }
   18776     }
   18777 
   18778     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   18779     public void monitor() {
   18780         synchronized (this) { }
   18781     }
   18782 
   18783     void onCoreSettingsChange(Bundle settings) {
   18784         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   18785             ProcessRecord processRecord = mLruProcesses.get(i);
   18786             try {
   18787                 if (processRecord.thread != null) {
   18788                     processRecord.thread.setCoreSettings(settings);
   18789                 }
   18790             } catch (RemoteException re) {
   18791                 /* ignore */
   18792             }
   18793         }
   18794     }
   18795 
   18796     // Multi-user methods
   18797 
   18798     /**
   18799      * Start user, if its not already running, but don't bring it to foreground.
   18800      */
   18801     @Override
   18802     public boolean startUserInBackground(final int userId) {
   18803         return startUser(userId, /* foreground */ false);
   18804     }
   18805 
   18806     /**
   18807      * Start user, if its not already running, and bring it to foreground.
   18808      */
   18809     boolean startUserInForeground(final int userId, Dialog dlg) {
   18810         boolean result = startUser(userId, /* foreground */ true);
   18811         dlg.dismiss();
   18812         return result;
   18813     }
   18814 
   18815     /**
   18816      * Refreshes the list of users related to the current user when either a
   18817      * user switch happens or when a new related user is started in the
   18818      * background.
   18819      */
   18820     private void updateCurrentProfileIdsLocked() {
   18821         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18822                 mCurrentUserId, false /* enabledOnly */);
   18823         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
   18824         for (int i = 0; i < currentProfileIds.length; i++) {
   18825             currentProfileIds[i] = profiles.get(i).id;
   18826         }
   18827         mCurrentProfileIds = currentProfileIds;
   18828 
   18829         synchronized (mUserProfileGroupIdsSelfLocked) {
   18830             mUserProfileGroupIdsSelfLocked.clear();
   18831             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
   18832             for (int i = 0; i < users.size(); i++) {
   18833                 UserInfo user = users.get(i);
   18834                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
   18835                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
   18836                 }
   18837             }
   18838         }
   18839     }
   18840 
   18841     private Set getProfileIdsLocked(int userId) {
   18842         Set userIds = new HashSet<Integer>();
   18843         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18844                 userId, false /* enabledOnly */);
   18845         for (UserInfo user : profiles) {
   18846             userIds.add(Integer.valueOf(user.id));
   18847         }
   18848         return userIds;
   18849     }
   18850 
   18851     @Override
   18852     public boolean switchUser(final int userId) {
   18853         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   18854         String userName;
   18855         synchronized (this) {
   18856             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18857             if (userInfo == null) {
   18858                 Slog.w(TAG, "No user info for user #" + userId);
   18859                 return false;
   18860             }
   18861             if (userInfo.isManagedProfile()) {
   18862                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18863                 return false;
   18864             }
   18865             userName = userInfo.name;
   18866             mTargetUserId = userId;
   18867         }
   18868         mHandler.removeMessages(START_USER_SWITCH_MSG);
   18869         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
   18870         return true;
   18871     }
   18872 
   18873     private void showUserSwitchDialog(int userId, String userName) {
   18874         // The dialog will show and then initiate the user switch by calling startUserInForeground
   18875         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
   18876                 true /* above system */);
   18877         d.show();
   18878     }
   18879 
   18880     private boolean startUser(final int userId, final boolean foreground) {
   18881         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18882                 != PackageManager.PERMISSION_GRANTED) {
   18883             String msg = "Permission Denial: switchUser() from pid="
   18884                     + Binder.getCallingPid()
   18885                     + ", uid=" + Binder.getCallingUid()
   18886                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   18887             Slog.w(TAG, msg);
   18888             throw new SecurityException(msg);
   18889         }
   18890 
   18891         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
   18892 
   18893         final long ident = Binder.clearCallingIdentity();
   18894         try {
   18895             synchronized (this) {
   18896                 final int oldUserId = mCurrentUserId;
   18897                 if (oldUserId == userId) {
   18898                     return true;
   18899                 }
   18900 
   18901                 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
   18902 
   18903                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18904                 if (userInfo == null) {
   18905                     Slog.w(TAG, "No user info for user #" + userId);
   18906                     return false;
   18907                 }
   18908                 if (foreground && userInfo.isManagedProfile()) {
   18909                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18910                     return false;
   18911                 }
   18912 
   18913                 if (foreground) {
   18914                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   18915                             R.anim.screen_user_enter);
   18916                 }
   18917 
   18918                 boolean needStart = false;
   18919 
   18920                 // If the user we are switching to is not currently started, then
   18921                 // we need to start it now.
   18922                 if (mStartedUsers.get(userId) == null) {
   18923                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   18924                     updateStartedUserArrayLocked();
   18925                     needStart = true;
   18926                 }
   18927 
   18928                 final Integer userIdInt = Integer.valueOf(userId);
   18929                 mUserLru.remove(userIdInt);
   18930                 mUserLru.add(userIdInt);
   18931 
   18932                 if (foreground) {
   18933                     mCurrentUserId = userId;
   18934                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
   18935                     updateCurrentProfileIdsLocked();
   18936                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
   18937                     // Once the internal notion of the active user has switched, we lock the device
   18938                     // with the option to show the user switcher on the keyguard.
   18939                     mWindowManager.lockNow(null);
   18940                 } else {
   18941                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
   18942                     updateCurrentProfileIdsLocked();
   18943                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
   18944                     mUserLru.remove(currentUserIdInt);
   18945                     mUserLru.add(currentUserIdInt);
   18946                 }
   18947 
   18948                 final UserStartedState uss = mStartedUsers.get(userId);
   18949 
   18950                 // Make sure user is in the started state.  If it is currently
   18951                 // stopping, we need to knock that off.
   18952                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   18953                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   18954                     // so we can just fairly silently bring the user back from
   18955                     // the almost-dead.
   18956                     uss.mState = UserStartedState.STATE_RUNNING;
   18957                     updateStartedUserArrayLocked();
   18958                     needStart = true;
   18959                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   18960                     // This means ACTION_SHUTDOWN has been sent, so we will
   18961                     // need to treat this as a new boot of the user.
   18962                     uss.mState = UserStartedState.STATE_BOOTING;
   18963                     updateStartedUserArrayLocked();
   18964                     needStart = true;
   18965                 }
   18966 
   18967                 if (uss.mState == UserStartedState.STATE_BOOTING) {
   18968                     // Booting up a new user, need to tell system services about it.
   18969                     // Note that this is on the same handler as scheduling of broadcasts,
   18970                     // which is important because it needs to go first.
   18971                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
   18972                 }
   18973 
   18974                 if (foreground) {
   18975                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
   18976                             oldUserId));
   18977                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   18978                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   18979                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   18980                             oldUserId, userId, uss));
   18981                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   18982                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   18983                 }
   18984 
   18985                 if (needStart) {
   18986                     // Send USER_STARTED broadcast
   18987                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   18988                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18989                             | Intent.FLAG_RECEIVER_FOREGROUND);
   18990                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18991                     broadcastIntentLocked(null, null, intent,
   18992                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18993                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   18994                 }
   18995 
   18996                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   18997                     if (userId != UserHandle.USER_OWNER) {
   18998                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   18999                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   19000                         broadcastIntentLocked(null, null, intent, null,
   19001                                 new IIntentReceiver.Stub() {
   19002                                     public void performReceive(Intent intent, int resultCode,
   19003                                             String data, Bundle extras, boolean ordered,
   19004                                             boolean sticky, int sendingUser) {
   19005                                         onUserInitialized(uss, foreground, oldUserId, userId);
   19006                                     }
   19007                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   19008                                 true, false, MY_PID, Process.SYSTEM_UID,
   19009                                 userId);
   19010                         uss.initializing = true;
   19011                     } else {
   19012                         getUserManagerLocked().makeInitialized(userInfo.id);
   19013                     }
   19014                 }
   19015 
   19016                 if (foreground) {
   19017                     if (!uss.initializing) {
   19018                         moveUserToForeground(uss, oldUserId, userId);
   19019                     }
   19020                 } else {
   19021                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
   19022                 }
   19023 
   19024                 if (needStart) {
   19025                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   19026                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19027                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19028                     broadcastIntentLocked(null, null, intent,
   19029                             null, new IIntentReceiver.Stub() {
   19030                                 @Override
   19031                                 public void performReceive(Intent intent, int resultCode, String data,
   19032                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   19033                                         throws RemoteException {
   19034                                 }
   19035                             }, 0, null, null,
   19036                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   19037                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19038                 }
   19039             }
   19040         } finally {
   19041             Binder.restoreCallingIdentity(ident);
   19042         }
   19043 
   19044         return true;
   19045     }
   19046 
   19047     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   19048         long ident = Binder.clearCallingIdentity();
   19049         try {
   19050             Intent intent;
   19051             if (oldUserId >= 0) {
   19052                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
   19053                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
   19054                 int count = profiles.size();
   19055                 for (int i = 0; i < count; i++) {
   19056                     int profileUserId = profiles.get(i).id;
   19057                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   19058                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19059                             | Intent.FLAG_RECEIVER_FOREGROUND);
   19060                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   19061                     broadcastIntentLocked(null, null, intent,
   19062                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19063                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   19064                 }
   19065             }
   19066             if (newUserId >= 0) {
   19067                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
   19068                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
   19069                 int count = profiles.size();
   19070                 for (int i = 0; i < count; i++) {
   19071                     int profileUserId = profiles.get(i).id;
   19072                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   19073                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19074                             | Intent.FLAG_RECEIVER_FOREGROUND);
   19075                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   19076                     broadcastIntentLocked(null, null, intent,
   19077                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19078                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   19079                 }
   19080                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   19081                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19082                         | Intent.FLAG_RECEIVER_FOREGROUND);
   19083                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   19084                 broadcastIntentLocked(null, null, intent,
   19085                         null, null, 0, null, null,
   19086                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   19087                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19088             }
   19089         } finally {
   19090             Binder.restoreCallingIdentity(ident);
   19091         }
   19092     }
   19093 
   19094     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   19095             final int newUserId) {
   19096         final int N = mUserSwitchObservers.beginBroadcast();
   19097         if (N > 0) {
   19098             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   19099                 int mCount = 0;
   19100                 @Override
   19101                 public void sendResult(Bundle data) throws RemoteException {
   19102                     synchronized (ActivityManagerService.this) {
   19103                         if (mCurUserSwitchCallback == this) {
   19104                             mCount++;
   19105                             if (mCount == N) {
   19106                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19107                             }
   19108                         }
   19109                     }
   19110                 }
   19111             };
   19112             synchronized (this) {
   19113                 uss.switching = true;
   19114                 mCurUserSwitchCallback = callback;
   19115             }
   19116             for (int i=0; i<N; i++) {
   19117                 try {
   19118                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   19119                             newUserId, callback);
   19120                 } catch (RemoteException e) {
   19121                 }
   19122             }
   19123         } else {
   19124             synchronized (this) {
   19125                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19126             }
   19127         }
   19128         mUserSwitchObservers.finishBroadcast();
   19129     }
   19130 
   19131     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   19132         synchronized (this) {
   19133             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   19134             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19135         }
   19136     }
   19137 
   19138     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   19139         mCurUserSwitchCallback = null;
   19140         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   19141         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   19142                 oldUserId, newUserId, uss));
   19143     }
   19144 
   19145     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
   19146         synchronized (this) {
   19147             if (foreground) {
   19148                 moveUserToForeground(uss, oldUserId, newUserId);
   19149             }
   19150         }
   19151 
   19152         completeSwitchAndInitalize(uss, newUserId, true, false);
   19153     }
   19154 
   19155     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
   19156         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
   19157         if (homeInFront) {
   19158             startHomeActivityLocked(newUserId, "moveUserToFroreground");
   19159         } else {
   19160             mStackSupervisor.resumeTopActivitiesLocked();
   19161         }
   19162         EventLogTags.writeAmSwitchUser(newUserId);
   19163         getUserManagerLocked().userForeground(newUserId);
   19164         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
   19165     }
   19166 
   19167     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   19168         completeSwitchAndInitalize(uss, newUserId, false, true);
   19169     }
   19170 
   19171     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   19172             boolean clearInitializing, boolean clearSwitching) {
   19173         boolean unfrozen = false;
   19174         synchronized (this) {
   19175             if (clearInitializing) {
   19176                 uss.initializing = false;
   19177                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   19178             }
   19179             if (clearSwitching) {
   19180                 uss.switching = false;
   19181             }
   19182             if (!uss.switching && !uss.initializing) {
   19183                 mWindowManager.stopFreezingScreen();
   19184                 unfrozen = true;
   19185             }
   19186         }
   19187         if (unfrozen) {
   19188             final int N = mUserSwitchObservers.beginBroadcast();
   19189             for (int i=0; i<N; i++) {
   19190                 try {
   19191                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   19192                 } catch (RemoteException e) {
   19193                 }
   19194             }
   19195             mUserSwitchObservers.finishBroadcast();
   19196         }
   19197         stopGuestUserIfBackground();
   19198     }
   19199 
   19200     /**
   19201      * Stops the guest user if it has gone to the background.
   19202      */
   19203     private void stopGuestUserIfBackground() {
   19204         synchronized (this) {
   19205             final int num = mUserLru.size();
   19206             for (int i = 0; i < num; i++) {
   19207                 Integer oldUserId = mUserLru.get(i);
   19208                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   19209                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
   19210                         || oldUss.mState == UserStartedState.STATE_STOPPING
   19211                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   19212                     continue;
   19213                 }
   19214                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
   19215                 if (userInfo.isGuest()) {
   19216                     // This is a user to be stopped.
   19217                     stopUserLocked(oldUserId, null);
   19218                     break;
   19219                 }
   19220             }
   19221         }
   19222     }
   19223 
   19224     void scheduleStartProfilesLocked() {
   19225         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   19226             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   19227                     DateUtils.SECOND_IN_MILLIS);
   19228         }
   19229     }
   19230 
   19231     void startProfilesLocked() {
   19232         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
   19233         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   19234                 mCurrentUserId, false /* enabledOnly */);
   19235         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
   19236         for (UserInfo user : profiles) {
   19237             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
   19238                     && user.id != mCurrentUserId) {
   19239                 toStart.add(user);
   19240             }
   19241         }
   19242         final int n = toStart.size();
   19243         int i = 0;
   19244         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
   19245             startUserInBackground(toStart.get(i).id);
   19246         }
   19247         if (i < n) {
   19248             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
   19249         }
   19250     }
   19251 
   19252     void finishUserBoot(UserStartedState uss) {
   19253         synchronized (this) {
   19254             if (uss.mState == UserStartedState.STATE_BOOTING
   19255                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   19256                 uss.mState = UserStartedState.STATE_RUNNING;
   19257                 final int userId = uss.mHandle.getIdentifier();
   19258                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   19259                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19260                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   19261                 broadcastIntentLocked(null, null, intent,
   19262                         null, null, 0, null, null,
   19263                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   19264                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   19265             }
   19266         }
   19267     }
   19268 
   19269     void finishUserSwitch(UserStartedState uss) {
   19270         synchronized (this) {
   19271             finishUserBoot(uss);
   19272 
   19273             startProfilesLocked();
   19274 
   19275             int num = mUserLru.size();
   19276             int i = 0;
   19277             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   19278                 Integer oldUserId = mUserLru.get(i);
   19279                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   19280                 if (oldUss == null) {
   19281                     // Shouldn't happen, but be sane if it does.
   19282                     mUserLru.remove(i);
   19283                     num--;
   19284                     continue;
   19285                 }
   19286                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   19287                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   19288                     // This user is already stopping, doesn't count.
   19289                     num--;
   19290                     i++;
   19291                     continue;
   19292                 }
   19293                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   19294                     // Owner and current can't be stopped, but count as running.
   19295                     i++;
   19296                     continue;
   19297                 }
   19298                 // This is a user to be stopped.
   19299                 stopUserLocked(oldUserId, null);
   19300                 num--;
   19301                 i++;
   19302             }
   19303         }
   19304     }
   19305 
   19306     @Override
   19307     public int stopUser(final int userId, final IStopUserCallback callback) {
   19308         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19309                 != PackageManager.PERMISSION_GRANTED) {
   19310             String msg = "Permission Denial: switchUser() from pid="
   19311                     + Binder.getCallingPid()
   19312                     + ", uid=" + Binder.getCallingUid()
   19313                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   19314             Slog.w(TAG, msg);
   19315             throw new SecurityException(msg);
   19316         }
   19317         if (userId <= 0) {
   19318             throw new IllegalArgumentException("Can't stop primary user " + userId);
   19319         }
   19320         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   19321         synchronized (this) {
   19322             return stopUserLocked(userId, callback);
   19323         }
   19324     }
   19325 
   19326     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   19327         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
   19328         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
   19329             return ActivityManager.USER_OP_IS_CURRENT;
   19330         }
   19331 
   19332         final UserStartedState uss = mStartedUsers.get(userId);
   19333         if (uss == null) {
   19334             // User is not started, nothing to do...  but we do need to
   19335             // callback if requested.
   19336             if (callback != null) {
   19337                 mHandler.post(new Runnable() {
   19338                     @Override
   19339                     public void run() {
   19340                         try {
   19341                             callback.userStopped(userId);
   19342                         } catch (RemoteException e) {
   19343                         }
   19344                     }
   19345                 });
   19346             }
   19347             return ActivityManager.USER_OP_SUCCESS;
   19348         }
   19349 
   19350         if (callback != null) {
   19351             uss.mStopCallbacks.add(callback);
   19352         }
   19353 
   19354         if (uss.mState != UserStartedState.STATE_STOPPING
   19355                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19356             uss.mState = UserStartedState.STATE_STOPPING;
   19357             updateStartedUserArrayLocked();
   19358 
   19359             long ident = Binder.clearCallingIdentity();
   19360             try {
   19361                 // We are going to broadcast ACTION_USER_STOPPING and then
   19362                 // once that is done send a final ACTION_SHUTDOWN and then
   19363                 // stop the user.
   19364                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   19365                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19366                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19367                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   19368                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   19369                 // This is the result receiver for the final shutdown broadcast.
   19370                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   19371                     @Override
   19372                     public void performReceive(Intent intent, int resultCode, String data,
   19373                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   19374                         finishUserStop(uss);
   19375                     }
   19376                 };
   19377                 // This is the result receiver for the initial stopping broadcast.
   19378                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   19379                     @Override
   19380                     public void performReceive(Intent intent, int resultCode, String data,
   19381                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   19382                         // On to the next.
   19383                         synchronized (ActivityManagerService.this) {
   19384                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   19385                                 // Whoops, we are being started back up.  Abort, abort!
   19386                                 return;
   19387                             }
   19388                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   19389                         }
   19390                         mBatteryStatsService.noteEvent(
   19391                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
   19392                                 Integer.toString(userId), userId);
   19393                         mSystemServiceManager.stopUser(userId);
   19394                         broadcastIntentLocked(null, null, shutdownIntent,
   19395                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   19396                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   19397                     }
   19398                 };
   19399                 // Kick things off.
   19400                 broadcastIntentLocked(null, null, stoppingIntent,
   19401                         null, stoppingReceiver, 0, null, null,
   19402                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   19403                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19404             } finally {
   19405                 Binder.restoreCallingIdentity(ident);
   19406             }
   19407         }
   19408 
   19409         return ActivityManager.USER_OP_SUCCESS;
   19410     }
   19411 
   19412     void finishUserStop(UserStartedState uss) {
   19413         final int userId = uss.mHandle.getIdentifier();
   19414         boolean stopped;
   19415         ArrayList<IStopUserCallback> callbacks;
   19416         synchronized (this) {
   19417             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   19418             if (mStartedUsers.get(userId) != uss) {
   19419                 stopped = false;
   19420             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19421                 stopped = false;
   19422             } else {
   19423                 stopped = true;
   19424                 // User can no longer run.
   19425                 mStartedUsers.remove(userId);
   19426                 mUserLru.remove(Integer.valueOf(userId));
   19427                 updateStartedUserArrayLocked();
   19428 
   19429                 // Clean up all state and processes associated with the user.
   19430                 // Kill all the processes for the user.
   19431                 forceStopUserLocked(userId, "finish user");
   19432             }
   19433 
   19434             // Explicitly remove the old information in mRecentTasks.
   19435             removeRecentTasksForUserLocked(userId);
   19436         }
   19437 
   19438         for (int i=0; i<callbacks.size(); i++) {
   19439             try {
   19440                 if (stopped) callbacks.get(i).userStopped(userId);
   19441                 else callbacks.get(i).userStopAborted(userId);
   19442             } catch (RemoteException e) {
   19443             }
   19444         }
   19445 
   19446         if (stopped) {
   19447             mSystemServiceManager.cleanupUser(userId);
   19448             synchronized (this) {
   19449                 mStackSupervisor.removeUserLocked(userId);
   19450             }
   19451         }
   19452     }
   19453 
   19454     @Override
   19455     public UserInfo getCurrentUser() {
   19456         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
   19457                 != PackageManager.PERMISSION_GRANTED) && (
   19458                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19459                 != PackageManager.PERMISSION_GRANTED)) {
   19460             String msg = "Permission Denial: getCurrentUser() from pid="
   19461                     + Binder.getCallingPid()
   19462                     + ", uid=" + Binder.getCallingUid()
   19463                     + " requires " + INTERACT_ACROSS_USERS;
   19464             Slog.w(TAG, msg);
   19465             throw new SecurityException(msg);
   19466         }
   19467         synchronized (this) {
   19468             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   19469             return getUserManagerLocked().getUserInfo(userId);
   19470         }
   19471     }
   19472 
   19473     int getCurrentUserIdLocked() {
   19474         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   19475     }
   19476 
   19477     @Override
   19478     public boolean isUserRunning(int userId, boolean orStopped) {
   19479         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   19480                 != PackageManager.PERMISSION_GRANTED) {
   19481             String msg = "Permission Denial: isUserRunning() from pid="
   19482                     + Binder.getCallingPid()
   19483                     + ", uid=" + Binder.getCallingUid()
   19484                     + " requires " + INTERACT_ACROSS_USERS;
   19485             Slog.w(TAG, msg);
   19486             throw new SecurityException(msg);
   19487         }
   19488         synchronized (this) {
   19489             return isUserRunningLocked(userId, orStopped);
   19490         }
   19491     }
   19492 
   19493     boolean isUserRunningLocked(int userId, boolean orStopped) {
   19494         UserStartedState state = mStartedUsers.get(userId);
   19495         if (state == null) {
   19496             return false;
   19497         }
   19498         if (orStopped) {
   19499             return true;
   19500         }
   19501         return state.mState != UserStartedState.STATE_STOPPING
   19502                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   19503     }
   19504 
   19505     @Override
   19506     public int[] getRunningUserIds() {
   19507         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   19508                 != PackageManager.PERMISSION_GRANTED) {
   19509             String msg = "Permission Denial: isUserRunning() from pid="
   19510                     + Binder.getCallingPid()
   19511                     + ", uid=" + Binder.getCallingUid()
   19512                     + " requires " + INTERACT_ACROSS_USERS;
   19513             Slog.w(TAG, msg);
   19514             throw new SecurityException(msg);
   19515         }
   19516         synchronized (this) {
   19517             return mStartedUserArray;
   19518         }
   19519     }
   19520 
   19521     private void updateStartedUserArrayLocked() {
   19522         int num = 0;
   19523         for (int i=0; i<mStartedUsers.size();  i++) {
   19524             UserStartedState uss = mStartedUsers.valueAt(i);
   19525             // This list does not include stopping users.
   19526             if (uss.mState != UserStartedState.STATE_STOPPING
   19527                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19528                 num++;
   19529             }
   19530         }
   19531         mStartedUserArray = new int[num];
   19532         num = 0;
   19533         for (int i=0; i<mStartedUsers.size();  i++) {
   19534             UserStartedState uss = mStartedUsers.valueAt(i);
   19535             if (uss.mState != UserStartedState.STATE_STOPPING
   19536                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19537                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   19538                 num++;
   19539             }
   19540         }
   19541     }
   19542 
   19543     @Override
   19544     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   19545         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19546                 != PackageManager.PERMISSION_GRANTED) {
   19547             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   19548                     + Binder.getCallingPid()
   19549                     + ", uid=" + Binder.getCallingUid()
   19550                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   19551             Slog.w(TAG, msg);
   19552             throw new SecurityException(msg);
   19553         }
   19554 
   19555         mUserSwitchObservers.register(observer);
   19556     }
   19557 
   19558     @Override
   19559     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   19560         mUserSwitchObservers.unregister(observer);
   19561     }
   19562 
   19563     private boolean userExists(int userId) {
   19564         if (userId == 0) {
   19565             return true;
   19566         }
   19567         UserManagerService ums = getUserManagerLocked();
   19568         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   19569     }
   19570 
   19571     int[] getUsersLocked() {
   19572         UserManagerService ums = getUserManagerLocked();
   19573         return ums != null ? ums.getUserIds() : new int[] { 0 };
   19574     }
   19575 
   19576     UserManagerService getUserManagerLocked() {
   19577         if (mUserManager == null) {
   19578             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   19579             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   19580         }
   19581         return mUserManager;
   19582     }
   19583 
   19584     private int applyUserId(int uid, int userId) {
   19585         return UserHandle.getUid(userId, uid);
   19586     }
   19587 
   19588     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   19589         if (info == null) return null;
   19590         ApplicationInfo newInfo = new ApplicationInfo(info);
   19591         newInfo.uid = applyUserId(info.uid, userId);
   19592         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   19593                 + info.packageName;
   19594         return newInfo;
   19595     }
   19596 
   19597     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   19598         if (aInfo == null
   19599                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   19600             return aInfo;
   19601         }
   19602 
   19603         ActivityInfo info = new ActivityInfo(aInfo);
   19604         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   19605         return info;
   19606     }
   19607 
   19608     private final class LocalService extends ActivityManagerInternal {
   19609         @Override
   19610         public void onWakefulnessChanged(int wakefulness) {
   19611             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   19612         }
   19613 
   19614         @Override
   19615         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   19616                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   19617             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   19618                     processName, abiOverride, uid, crashHandler);
   19619         }
   19620     }
   19621 
   19622     /**
   19623      * An implementation of IAppTask, that allows an app to manage its own tasks via
   19624      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   19625      * only the process that calls getAppTasks() can call the AppTask methods.
   19626      */
   19627     class AppTaskImpl extends IAppTask.Stub {
   19628         private int mTaskId;
   19629         private int mCallingUid;
   19630 
   19631         public AppTaskImpl(int taskId, int callingUid) {
   19632             mTaskId = taskId;
   19633             mCallingUid = callingUid;
   19634         }
   19635 
   19636         private void checkCaller() {
   19637             if (mCallingUid != Binder.getCallingUid()) {
   19638                 throw new SecurityException("Caller " + mCallingUid
   19639                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   19640             }
   19641         }
   19642 
   19643         @Override
   19644         public void finishAndRemoveTask() {
   19645             checkCaller();
   19646 
   19647             synchronized (ActivityManagerService.this) {
   19648                 long origId = Binder.clearCallingIdentity();
   19649                 try {
   19650                     if (!removeTaskByIdLocked(mTaskId, false)) {
   19651                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19652                     }
   19653                 } finally {
   19654                     Binder.restoreCallingIdentity(origId);
   19655                 }
   19656             }
   19657         }
   19658 
   19659         @Override
   19660         public ActivityManager.RecentTaskInfo getTaskInfo() {
   19661             checkCaller();
   19662 
   19663             synchronized (ActivityManagerService.this) {
   19664                 long origId = Binder.clearCallingIdentity();
   19665                 try {
   19666                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19667                     if (tr == null) {
   19668                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19669                     }
   19670                     return createRecentTaskInfoFromTaskRecord(tr);
   19671                 } finally {
   19672                     Binder.restoreCallingIdentity(origId);
   19673                 }
   19674             }
   19675         }
   19676 
   19677         @Override
   19678         public void moveToFront() {
   19679             checkCaller();
   19680             // Will bring task to front if it already has a root activity.
   19681             startActivityFromRecentsInner(mTaskId, null);
   19682         }
   19683 
   19684         @Override
   19685         public int startActivity(IBinder whoThread, String callingPackage,
   19686                 Intent intent, String resolvedType, Bundle options) {
   19687             checkCaller();
   19688 
   19689             int callingUser = UserHandle.getCallingUserId();
   19690             TaskRecord tr;
   19691             IApplicationThread appThread;
   19692             synchronized (ActivityManagerService.this) {
   19693                 tr = recentTaskForIdLocked(mTaskId);
   19694                 if (tr == null) {
   19695                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19696                 }
   19697                 appThread = ApplicationThreadNative.asInterface(whoThread);
   19698                 if (appThread == null) {
   19699                     throw new IllegalArgumentException("Bad app thread " + appThread);
   19700                 }
   19701             }
   19702             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
   19703                     resolvedType, null, null, null, null, 0, 0, null, null,
   19704                     null, options, callingUser, null, tr);
   19705         }
   19706 
   19707         @Override
   19708         public void setExcludeFromRecents(boolean exclude) {
   19709             checkCaller();
   19710 
   19711             synchronized (ActivityManagerService.this) {
   19712                 long origId = Binder.clearCallingIdentity();
   19713                 try {
   19714                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19715                     if (tr == null) {
   19716                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19717                     }
   19718                     Intent intent = tr.getBaseIntent();
   19719                     if (exclude) {
   19720                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19721                     } else {
   19722                         intent.setFlags(intent.getFlags()
   19723                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19724                     }
   19725                 } finally {
   19726                     Binder.restoreCallingIdentity(origId);
   19727                 }
   19728             }
   19729         }
   19730     }
   19731 }
   19732