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 N = procs.size();
   2695             for (int i = 0; i < N; i++) {
   2696                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   2697             }
   2698         }
   2699         ProcessRecord proc = mProcessNames.get(processName, uid);
   2700         if (false && proc != null && !keepIfLarge
   2701                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   2702                 && proc.lastCachedPss >= 4000) {
   2703             // Turn this condition on to cause killing to happen regularly, for testing.
   2704             if (proc.baseProcessTracker != null) {
   2705                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2706             }
   2707             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2708         } else if (proc != null && !keepIfLarge
   2709                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   2710                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2711             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   2712             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   2713                 if (proc.baseProcessTracker != null) {
   2714                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2715                 }
   2716                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2717             }
   2718         }
   2719         return proc;
   2720     }
   2721 
   2722     void ensurePackageDexOpt(String packageName) {
   2723         IPackageManager pm = AppGlobals.getPackageManager();
   2724         try {
   2725             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
   2726                 mDidDexOpt = true;
   2727             }
   2728         } catch (RemoteException e) {
   2729         }
   2730     }
   2731 
   2732     boolean isNextTransitionForward() {
   2733         int transit = mWindowManager.getPendingAppTransition();
   2734         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2735                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2736                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2737     }
   2738 
   2739     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   2740             String processName, String abiOverride, int uid, Runnable crashHandler) {
   2741         synchronized(this) {
   2742             ApplicationInfo info = new ApplicationInfo();
   2743             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   2744             // For isolated processes, the former contains the parent's uid and the latter the
   2745             // actual uid of the isolated process.
   2746             // In the special case introduced by this method (which is, starting an isolated
   2747             // process directly from the SystemServer without an actual parent app process) the
   2748             // closest thing to a parent's uid is SYSTEM_UID.
   2749             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   2750             // the |isolated| logic in the ProcessRecord constructor.
   2751             info.uid = Process.SYSTEM_UID;
   2752             info.processName = processName;
   2753             info.className = entryPoint;
   2754             info.packageName = "android";
   2755             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   2756                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   2757                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   2758                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   2759                     crashHandler);
   2760             return proc != null ? proc.pid : 0;
   2761         }
   2762     }
   2763 
   2764     final ProcessRecord startProcessLocked(String processName,
   2765             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2766             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2767             boolean isolated, boolean keepIfLarge) {
   2768         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   2769                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   2770                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   2771                 null /* crashHandler */);
   2772     }
   2773 
   2774     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   2775             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   2776             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   2777             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   2778         long startTime = SystemClock.elapsedRealtime();
   2779         ProcessRecord app;
   2780         if (!isolated) {
   2781             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   2782             checkTime(startTime, "startProcess: after getProcessRecord");
   2783         } else {
   2784             // If this is an isolated process, it can't re-use an existing process.
   2785             app = null;
   2786         }
   2787         // We don't have to do anything more if:
   2788         // (1) There is an existing application record; and
   2789         // (2) The caller doesn't think it is dead, OR there is no thread
   2790         //     object attached to it so we know it couldn't have crashed; and
   2791         // (3) There is a pid assigned to it, so it is either starting or
   2792         //     already running.
   2793         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2794                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2795                 + " thread=" + (app != null ? app.thread : null)
   2796                 + " pid=" + (app != null ? app.pid : -1));
   2797         if (app != null && app.pid > 0) {
   2798             if (!knownToBeDead || app.thread == null) {
   2799                 // We already have the app running, or are waiting for it to
   2800                 // come up (we have a pid but not yet its thread), so keep it.
   2801                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2802                 // If this is a new package in the process, add the package to the list
   2803                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   2804                 checkTime(startTime, "startProcess: done, added package to proc");
   2805                 return app;
   2806             }
   2807 
   2808             // An application record is attached to a previous process,
   2809             // clean it up now.
   2810             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2811             checkTime(startTime, "startProcess: bad proc running, killing");
   2812             Process.killProcessGroup(app.info.uid, app.pid);
   2813             handleAppDiedLocked(app, true, true);
   2814             checkTime(startTime, "startProcess: done killing old proc");
   2815         }
   2816 
   2817         String hostingNameStr = hostingName != null
   2818                 ? hostingName.flattenToShortString() : null;
   2819 
   2820         if (!isolated) {
   2821             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   2822                 // If we are in the background, then check to see if this process
   2823                 // is bad.  If so, we will just silently fail.
   2824                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2825                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   2826                             + "/" + info.processName);
   2827                     return null;
   2828                 }
   2829             } else {
   2830                 // When the user is explicitly starting a process, then clear its
   2831                 // crash count so that we won't make it bad until they see at
   2832                 // least one crash dialog again, and make the process good again
   2833                 // if it had been bad.
   2834                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   2835                         + "/" + info.processName);
   2836                 mProcessCrashTimes.remove(info.processName, info.uid);
   2837                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2838                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2839                             UserHandle.getUserId(info.uid), info.uid,
   2840                             info.processName);
   2841                     mBadProcesses.remove(info.processName, info.uid);
   2842                     if (app != null) {
   2843                         app.bad = false;
   2844                     }
   2845                 }
   2846             }
   2847         }
   2848 
   2849         if (app == null) {
   2850             checkTime(startTime, "startProcess: creating new process record");
   2851             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   2852             if (app == null) {
   2853                 Slog.w(TAG, "Failed making new process record for "
   2854                         + processName + "/" + info.uid + " isolated=" + isolated);
   2855                 return null;
   2856             }
   2857             app.crashHandler = crashHandler;
   2858             mProcessNames.put(processName, app.uid, app);
   2859             if (isolated) {
   2860                 mIsolatedProcesses.put(app.uid, app);
   2861             }
   2862             checkTime(startTime, "startProcess: done creating new process record");
   2863         } else {
   2864             // If this is a new package in the process, add the package to the list
   2865             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   2866             checkTime(startTime, "startProcess: added package to existing proc");
   2867         }
   2868 
   2869         // If the system is not ready yet, then hold off on starting this
   2870         // process until it is.
   2871         if (!mProcessesReady
   2872                 && !isAllowedWhileBooting(info)
   2873                 && !allowWhileBooting) {
   2874             if (!mProcessesOnHold.contains(app)) {
   2875                 mProcessesOnHold.add(app);
   2876             }
   2877             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2878             checkTime(startTime, "startProcess: returning with proc on hold");
   2879             return app;
   2880         }
   2881 
   2882         checkTime(startTime, "startProcess: stepping in to startProcess");
   2883         startProcessLocked(
   2884                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   2885         checkTime(startTime, "startProcess: done starting proc!");
   2886         return (app.pid != 0) ? app : null;
   2887     }
   2888 
   2889     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2890         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2891     }
   2892 
   2893     private final void startProcessLocked(ProcessRecord app,
   2894             String hostingType, String hostingNameStr) {
   2895         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   2896                 null /* entryPoint */, null /* entryPointArgs */);
   2897     }
   2898 
   2899     private final void startProcessLocked(ProcessRecord app, String hostingType,
   2900             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   2901         long startTime = SystemClock.elapsedRealtime();
   2902         if (app.pid > 0 && app.pid != MY_PID) {
   2903             checkTime(startTime, "startProcess: removing from pids map");
   2904             synchronized (mPidsSelfLocked) {
   2905                 mPidsSelfLocked.remove(app.pid);
   2906                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2907             }
   2908             checkTime(startTime, "startProcess: done removing from pids map");
   2909             app.setPid(0);
   2910         }
   2911 
   2912         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2913                 "startProcessLocked removing on hold: " + app);
   2914         mProcessesOnHold.remove(app);
   2915 
   2916         checkTime(startTime, "startProcess: starting to update cpu stats");
   2917         updateCpuStats();
   2918         checkTime(startTime, "startProcess: done updating cpu stats");
   2919 
   2920         try {
   2921             int uid = app.uid;
   2922 
   2923             int[] gids = null;
   2924             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2925             if (!app.isolated) {
   2926                 int[] permGids = null;
   2927                 try {
   2928                     checkTime(startTime, "startProcess: getting gids from package manager");
   2929                     final PackageManager pm = mContext.getPackageManager();
   2930                     permGids = pm.getPackageGids(app.info.packageName);
   2931 
   2932                     if (Environment.isExternalStorageEmulated()) {
   2933                         checkTime(startTime, "startProcess: checking external storage perm");
   2934                         if (pm.checkPermission(
   2935                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2936                                 app.info.packageName) == PERMISSION_GRANTED) {
   2937                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2938                         } else {
   2939                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2940                         }
   2941                     }
   2942                 } catch (PackageManager.NameNotFoundException e) {
   2943                     Slog.w(TAG, "Unable to retrieve gids", e);
   2944                 }
   2945 
   2946                 /*
   2947                  * Add shared application and profile GIDs so applications can share some
   2948                  * resources like shared libraries and access user-wide resources
   2949                  */
   2950                 if (permGids == null) {
   2951                     gids = new int[2];
   2952                 } else {
   2953                     gids = new int[permGids.length + 2];
   2954                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   2955                 }
   2956                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2957                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   2958             }
   2959             checkTime(startTime, "startProcess: building args");
   2960             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   2961                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   2962                         && mTopComponent != null
   2963                         && app.processName.equals(mTopComponent.getPackageName())) {
   2964                     uid = 0;
   2965                 }
   2966                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   2967                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2968                     uid = 0;
   2969                 }
   2970             }
   2971             int debugFlags = 0;
   2972             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2973                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2974                 // Also turn on CheckJNI for debuggable apps. It's quite
   2975                 // awkward to turn on otherwise.
   2976                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2977             }
   2978             // Run the app in safe mode if its manifest requests so or the
   2979             // system is booted in safe mode.
   2980             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2981                 mSafeMode == true) {
   2982                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2983             }
   2984             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2985                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2986             }
   2987             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2988                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2989             }
   2990             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2991                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2992             }
   2993 
   2994             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   2995             if (requiredAbi == null) {
   2996                 requiredAbi = Build.SUPPORTED_ABIS[0];
   2997             }
   2998 
   2999             String instructionSet = null;
   3000             if (app.info.primaryCpuAbi != null) {
   3001                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3002             }
   3003 
   3004             app.gids = gids;
   3005             app.requiredAbi = requiredAbi;
   3006             app.instructionSet = instructionSet;
   3007 
   3008             // Start the process.  It will either succeed and return a result containing
   3009             // the PID of the new process, or else throw a RuntimeException.
   3010             boolean isActivityProcess = (entryPoint == null);
   3011             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3012             checkTime(startTime, "startProcess: asking zygote to start proc");
   3013             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3014                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3015                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3016                     app.info.dataDir, entryPointArgs);
   3017             checkTime(startTime, "startProcess: returned from zygote!");
   3018 
   3019             if (app.isolated) {
   3020                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
   3021             }
   3022             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3023             checkTime(startTime, "startProcess: done updating battery stats");
   3024 
   3025             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3026                     UserHandle.getUserId(uid), startResult.pid, uid,
   3027                     app.processName, hostingType,
   3028                     hostingNameStr != null ? hostingNameStr : "");
   3029 
   3030             if (app.persistent) {
   3031                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3032             }
   3033 
   3034             checkTime(startTime, "startProcess: building log message");
   3035             StringBuilder buf = mStringBuilder;
   3036             buf.setLength(0);
   3037             buf.append("Start proc ");
   3038             buf.append(startResult.pid);
   3039             buf.append(':');
   3040             buf.append(app.processName);
   3041             buf.append('/');
   3042             UserHandle.formatUid(buf, uid);
   3043             if (!isActivityProcess) {
   3044                 buf.append(" [");
   3045                 buf.append(entryPoint);
   3046                 buf.append("]");
   3047             }
   3048             buf.append(" for ");
   3049             buf.append(hostingType);
   3050             if (hostingNameStr != null) {
   3051                 buf.append(" ");
   3052                 buf.append(hostingNameStr);
   3053             }
   3054             Slog.i(TAG, buf.toString());
   3055             app.setPid(startResult.pid);
   3056             app.usingWrapper = startResult.usingWrapper;
   3057             app.removed = false;
   3058             app.killed = false;
   3059             app.killedByAm = false;
   3060             checkTime(startTime, "startProcess: starting to update pids map");
   3061             synchronized (mPidsSelfLocked) {
   3062                 this.mPidsSelfLocked.put(startResult.pid, app);
   3063                 if (isActivityProcess) {
   3064                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3065                     msg.obj = app;
   3066                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3067                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3068                 }
   3069             }
   3070             checkTime(startTime, "startProcess: done updating pids map");
   3071         } catch (RuntimeException e) {
   3072             // XXX do better error recovery.
   3073             app.setPid(0);
   3074             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   3075             if (app.isolated) {
   3076                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   3077             }
   3078             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3079         }
   3080     }
   3081 
   3082     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3083         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
   3084         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3085         if (resumed) {
   3086             if (mUsageStatsService != null) {
   3087                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3088                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3089             }
   3090             synchronized (stats) {
   3091                 stats.noteActivityResumedLocked(component.app.uid);
   3092             }
   3093         } else {
   3094             if (mUsageStatsService != null) {
   3095                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3096                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3097             }
   3098             synchronized (stats) {
   3099                 stats.noteActivityPausedLocked(component.app.uid);
   3100             }
   3101         }
   3102     }
   3103 
   3104     Intent getHomeIntent() {
   3105         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3106         intent.setComponent(mTopComponent);
   3107         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3108             intent.addCategory(Intent.CATEGORY_HOME);
   3109         }
   3110         return intent;
   3111     }
   3112 
   3113     boolean startHomeActivityLocked(int userId, String reason) {
   3114         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3115                 && mTopAction == null) {
   3116             // We are running in factory test mode, but unable to find
   3117             // the factory test app, so just sit around displaying the
   3118             // error message and don't try to start anything.
   3119             return false;
   3120         }
   3121         Intent intent = getHomeIntent();
   3122         ActivityInfo aInfo =
   3123             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3124         if (aInfo != null) {
   3125             intent.setComponent(new ComponentName(
   3126                     aInfo.applicationInfo.packageName, aInfo.name));
   3127             // Don't do this if the home app is currently being
   3128             // instrumented.
   3129             aInfo = new ActivityInfo(aInfo);
   3130             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3131             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3132                     aInfo.applicationInfo.uid, true);
   3133             if (app == null || app.instrumentationClass == null) {
   3134                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3135                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
   3136             }
   3137         }
   3138 
   3139         return true;
   3140     }
   3141 
   3142     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3143         ActivityInfo ai = null;
   3144         ComponentName comp = intent.getComponent();
   3145         try {
   3146             if (comp != null) {
   3147                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3148             } else {
   3149                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3150                         intent,
   3151                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3152                             flags, userId);
   3153 
   3154                 if (info != null) {
   3155                     ai = info.activityInfo;
   3156                 }
   3157             }
   3158         } catch (RemoteException e) {
   3159             // ignore
   3160         }
   3161 
   3162         return ai;
   3163     }
   3164 
   3165     /**
   3166      * Starts the "new version setup screen" if appropriate.
   3167      */
   3168     void startSetupActivityLocked() {
   3169         // Only do this once per boot.
   3170         if (mCheckedForSetup) {
   3171             return;
   3172         }
   3173 
   3174         // We will show this screen if the current one is a different
   3175         // version than the last one shown, and we are not running in
   3176         // low-level factory test mode.
   3177         final ContentResolver resolver = mContext.getContentResolver();
   3178         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3179                 Settings.Global.getInt(resolver,
   3180                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3181             mCheckedForSetup = true;
   3182 
   3183             // See if we should be showing the platform update setup UI.
   3184             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3185             List<ResolveInfo> ris = mContext.getPackageManager()
   3186                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   3187 
   3188             // We don't allow third party apps to replace this.
   3189             ResolveInfo ri = null;
   3190             for (int i=0; ris != null && i<ris.size(); i++) {
   3191                 if ((ris.get(i).activityInfo.applicationInfo.flags
   3192                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   3193                     ri = ris.get(i);
   3194                     break;
   3195                 }
   3196             }
   3197 
   3198             if (ri != null) {
   3199                 String vers = ri.activityInfo.metaData != null
   3200                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3201                         : null;
   3202                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   3203                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   3204                             Intent.METADATA_SETUP_VERSION);
   3205                 }
   3206                 String lastVers = Settings.Secure.getString(
   3207                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   3208                 if (vers != null && !vers.equals(lastVers)) {
   3209                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3210                     intent.setComponent(new ComponentName(
   3211                             ri.activityInfo.packageName, ri.activityInfo.name));
   3212                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
   3213                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
   3214                             null);
   3215                 }
   3216             }
   3217         }
   3218     }
   3219 
   3220     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   3221         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   3222     }
   3223 
   3224     void enforceNotIsolatedCaller(String caller) {
   3225         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   3226             throw new SecurityException("Isolated process not allowed to call " + caller);
   3227         }
   3228     }
   3229 
   3230     void enforceShellRestriction(String restriction, int userHandle) {
   3231         if (Binder.getCallingUid() == Process.SHELL_UID) {
   3232             if (userHandle < 0
   3233                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
   3234                 throw new SecurityException("Shell does not have permission to access user "
   3235                         + userHandle);
   3236             }
   3237         }
   3238     }
   3239 
   3240     @Override
   3241     public int getFrontActivityScreenCompatMode() {
   3242         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   3243         synchronized (this) {
   3244             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   3245         }
   3246     }
   3247 
   3248     @Override
   3249     public void setFrontActivityScreenCompatMode(int mode) {
   3250         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3251                 "setFrontActivityScreenCompatMode");
   3252         synchronized (this) {
   3253             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   3254         }
   3255     }
   3256 
   3257     @Override
   3258     public int getPackageScreenCompatMode(String packageName) {
   3259         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   3260         synchronized (this) {
   3261             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   3262         }
   3263     }
   3264 
   3265     @Override
   3266     public void setPackageScreenCompatMode(String packageName, int mode) {
   3267         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3268                 "setPackageScreenCompatMode");
   3269         synchronized (this) {
   3270             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   3271         }
   3272     }
   3273 
   3274     @Override
   3275     public boolean getPackageAskScreenCompat(String packageName) {
   3276         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   3277         synchronized (this) {
   3278             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   3279         }
   3280     }
   3281 
   3282     @Override
   3283     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   3284         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3285                 "setPackageAskScreenCompat");
   3286         synchronized (this) {
   3287             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   3288         }
   3289     }
   3290 
   3291     private void dispatchProcessesChanged() {
   3292         int N;
   3293         synchronized (this) {
   3294             N = mPendingProcessChanges.size();
   3295             if (mActiveProcessChanges.length < N) {
   3296                 mActiveProcessChanges = new ProcessChangeItem[N];
   3297             }
   3298             mPendingProcessChanges.toArray(mActiveProcessChanges);
   3299             mAvailProcessChanges.addAll(mPendingProcessChanges);
   3300             mPendingProcessChanges.clear();
   3301             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   3302         }
   3303 
   3304         int i = mProcessObservers.beginBroadcast();
   3305         while (i > 0) {
   3306             i--;
   3307             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3308             if (observer != null) {
   3309                 try {
   3310                     for (int j=0; j<N; j++) {
   3311                         ProcessChangeItem item = mActiveProcessChanges[j];
   3312                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   3313                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   3314                                     + item.pid + " uid=" + item.uid + ": "
   3315                                     + item.foregroundActivities);
   3316                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   3317                                     item.foregroundActivities);
   3318                         }
   3319                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   3320                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
   3321                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
   3322                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   3323                         }
   3324                     }
   3325                 } catch (RemoteException e) {
   3326                 }
   3327             }
   3328         }
   3329         mProcessObservers.finishBroadcast();
   3330     }
   3331 
   3332     private void dispatchProcessDied(int pid, int uid) {
   3333         int i = mProcessObservers.beginBroadcast();
   3334         while (i > 0) {
   3335             i--;
   3336             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3337             if (observer != null) {
   3338                 try {
   3339                     observer.onProcessDied(pid, uid);
   3340                 } catch (RemoteException e) {
   3341                 }
   3342             }
   3343         }
   3344         mProcessObservers.finishBroadcast();
   3345     }
   3346 
   3347     @Override
   3348     public final int startActivity(IApplicationThread caller, String callingPackage,
   3349             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3350             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
   3351         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   3352             resultWho, requestCode, startFlags, profilerInfo, options,
   3353             UserHandle.getCallingUserId());
   3354     }
   3355 
   3356     @Override
   3357     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   3358             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3359             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3360         enforceNotIsolatedCaller("startActivity");
   3361         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3362                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3363         // TODO: Switch to user app stacks here.
   3364         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3365                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3366                 profilerInfo, null, null, options, userId, null, null);
   3367     }
   3368 
   3369     @Override
   3370     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   3371             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3372             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3373 
   3374         // This is very dangerous -- it allows you to perform a start activity (including
   3375         // permission grants) as any app that may launch one of your own activities.  So
   3376         // we will only allow this to be done from activities that are part of the core framework,
   3377         // and then only when they are running as the system.
   3378         final ActivityRecord sourceRecord;
   3379         final int targetUid;
   3380         final String targetPackage;
   3381         synchronized (this) {
   3382             if (resultTo == null) {
   3383                 throw new SecurityException("Must be called from an activity");
   3384             }
   3385             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   3386             if (sourceRecord == null) {
   3387                 throw new SecurityException("Called with bad activity token: " + resultTo);
   3388             }
   3389             if (!sourceRecord.info.packageName.equals("android")) {
   3390                 throw new SecurityException(
   3391                         "Must be called from an activity that is declared in the android package");
   3392             }
   3393             if (sourceRecord.app == null) {
   3394                 throw new SecurityException("Called without a process attached to activity");
   3395             }
   3396             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   3397                 // This is still okay, as long as this activity is running under the
   3398                 // uid of the original calling activity.
   3399                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   3400                     throw new SecurityException(
   3401                             "Calling activity in uid " + sourceRecord.app.uid
   3402                                     + " must be system uid or original calling uid "
   3403                                     + sourceRecord.launchedFromUid);
   3404                 }
   3405             }
   3406             targetUid = sourceRecord.launchedFromUid;
   3407             targetPackage = sourceRecord.launchedFromPackage;
   3408         }
   3409 
   3410         if (userId == UserHandle.USER_NULL) {
   3411             userId = UserHandle.getUserId(sourceRecord.app.uid);
   3412         }
   3413 
   3414         // TODO: Switch to user app stacks here.
   3415         try {
   3416             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
   3417                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   3418                     null, null, options, userId, null, null);
   3419             return ret;
   3420         } catch (SecurityException e) {
   3421             // XXX need to figure out how to propagate to original app.
   3422             // A SecurityException here is generally actually a fault of the original
   3423             // calling activity (such as a fairly granting permissions), so propagate it
   3424             // back to them.
   3425             /*
   3426             StringBuilder msg = new StringBuilder();
   3427             msg.append("While launching");
   3428             msg.append(intent.toString());
   3429             msg.append(": ");
   3430             msg.append(e.getMessage());
   3431             */
   3432             throw e;
   3433         }
   3434     }
   3435 
   3436     @Override
   3437     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   3438             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3439             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3440         enforceNotIsolatedCaller("startActivityAndWait");
   3441         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3442                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   3443         WaitResult res = new WaitResult();
   3444         // TODO: Switch to user app stacks here.
   3445         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   3446                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   3447                 options, userId, null, null);
   3448         return res;
   3449     }
   3450 
   3451     @Override
   3452     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   3453             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3454             int startFlags, Configuration config, Bundle options, int userId) {
   3455         enforceNotIsolatedCaller("startActivityWithConfig");
   3456         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3457                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   3458         // TODO: Switch to user app stacks here.
   3459         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3460                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3461                 null, null, config, options, userId, null, null);
   3462         return ret;
   3463     }
   3464 
   3465     @Override
   3466     public int startActivityIntentSender(IApplicationThread caller,
   3467             IntentSender intent, Intent fillInIntent, String resolvedType,
   3468             IBinder resultTo, String resultWho, int requestCode,
   3469             int flagsMask, int flagsValues, Bundle options) {
   3470         enforceNotIsolatedCaller("startActivityIntentSender");
   3471         // Refuse possible leaked file descriptors
   3472         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3473             throw new IllegalArgumentException("File descriptors passed in Intent");
   3474         }
   3475 
   3476         IIntentSender sender = intent.getTarget();
   3477         if (!(sender instanceof PendingIntentRecord)) {
   3478             throw new IllegalArgumentException("Bad PendingIntent object");
   3479         }
   3480 
   3481         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3482 
   3483         synchronized (this) {
   3484             // If this is coming from the currently resumed activity, it is
   3485             // effectively saying that app switches are allowed at this point.
   3486             final ActivityStack stack = getFocusedStack();
   3487             if (stack.mResumedActivity != null &&
   3488                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   3489                 mAppSwitchesAllowedTime = 0;
   3490             }
   3491         }
   3492         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   3493                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
   3494         return ret;
   3495     }
   3496 
   3497     @Override
   3498     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   3499             Intent intent, String resolvedType, IVoiceInteractionSession session,
   3500             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   3501             Bundle options, int userId) {
   3502         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   3503                 != PackageManager.PERMISSION_GRANTED) {
   3504             String msg = "Permission Denial: startVoiceActivity() from pid="
   3505                     + Binder.getCallingPid()
   3506                     + ", uid=" + Binder.getCallingUid()
   3507                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   3508             Slog.w(TAG, msg);
   3509             throw new SecurityException(msg);
   3510         }
   3511         if (session == null || interactor == null) {
   3512             throw new NullPointerException("null session or interactor");
   3513         }
   3514         userId = handleIncomingUser(callingPid, callingUid, userId,
   3515                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
   3516         // TODO: Switch to user app stacks here.
   3517         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
   3518                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   3519                 null, options, userId, null, null);
   3520     }
   3521 
   3522     @Override
   3523     public boolean startNextMatchingActivity(IBinder callingActivity,
   3524             Intent intent, Bundle options) {
   3525         // Refuse possible leaked file descriptors
   3526         if (intent != null && intent.hasFileDescriptors() == true) {
   3527             throw new IllegalArgumentException("File descriptors passed in Intent");
   3528         }
   3529 
   3530         synchronized (this) {
   3531             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   3532             if (r == null) {
   3533                 ActivityOptions.abort(options);
   3534                 return false;
   3535             }
   3536             if (r.app == null || r.app.thread == null) {
   3537                 // The caller is not running...  d'oh!
   3538                 ActivityOptions.abort(options);
   3539                 return false;
   3540             }
   3541             intent = new Intent(intent);
   3542             // The caller is not allowed to change the data.
   3543             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3544             // And we are resetting to find the next component...
   3545             intent.setComponent(null);
   3546 
   3547             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3548 
   3549             ActivityInfo aInfo = null;
   3550             try {
   3551                 List<ResolveInfo> resolves =
   3552                     AppGlobals.getPackageManager().queryIntentActivities(
   3553                             intent, r.resolvedType,
   3554                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   3555                             UserHandle.getCallingUserId());
   3556 
   3557                 // Look for the original activity in the list...
   3558                 final int N = resolves != null ? resolves.size() : 0;
   3559                 for (int i=0; i<N; i++) {
   3560                     ResolveInfo rInfo = resolves.get(i);
   3561                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3562                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3563                         // We found the current one...  the next matching is
   3564                         // after it.
   3565                         i++;
   3566                         if (i<N) {
   3567                             aInfo = resolves.get(i).activityInfo;
   3568                         }
   3569                         if (debug) {
   3570                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   3571                                     + "/" + r.info.name);
   3572                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
   3573                                     + "/" + aInfo.name);
   3574                         }
   3575                         break;
   3576                     }
   3577                 }
   3578             } catch (RemoteException e) {
   3579             }
   3580 
   3581             if (aInfo == null) {
   3582                 // Nobody who is next!
   3583                 ActivityOptions.abort(options);
   3584                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   3585                 return false;
   3586             }
   3587 
   3588             intent.setComponent(new ComponentName(
   3589                     aInfo.applicationInfo.packageName, aInfo.name));
   3590             intent.setFlags(intent.getFlags()&~(
   3591                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3592                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3593                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3594                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3595 
   3596             // Okay now we need to start the new activity, replacing the
   3597             // currently running activity.  This is a little tricky because
   3598             // we want to start the new one as if the current one is finished,
   3599             // but not finish the current one first so that there is no flicker.
   3600             // And thus...
   3601             final boolean wasFinishing = r.finishing;
   3602             r.finishing = true;
   3603 
   3604             // Propagate reply information over to the new activity.
   3605             final ActivityRecord resultTo = r.resultTo;
   3606             final String resultWho = r.resultWho;
   3607             final int requestCode = r.requestCode;
   3608             r.resultTo = null;
   3609             if (resultTo != null) {
   3610                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3611             }
   3612 
   3613             final long origId = Binder.clearCallingIdentity();
   3614             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
   3615                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
   3616                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
   3617                     -1, r.launchedFromUid, 0, options, false, null, null, null);
   3618             Binder.restoreCallingIdentity(origId);
   3619 
   3620             r.finishing = wasFinishing;
   3621             if (res != ActivityManager.START_SUCCESS) {
   3622                 return false;
   3623             }
   3624             return true;
   3625         }
   3626     }
   3627 
   3628     @Override
   3629     public final int startActivityFromRecents(int taskId, Bundle options) {
   3630         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   3631             String msg = "Permission Denial: startActivityFromRecents called without " +
   3632                     START_TASKS_FROM_RECENTS;
   3633             Slog.w(TAG, msg);
   3634             throw new SecurityException(msg);
   3635         }
   3636         return startActivityFromRecentsInner(taskId, options);
   3637     }
   3638 
   3639     final int startActivityFromRecentsInner(int taskId, Bundle options) {
   3640         final TaskRecord task;
   3641         final int callingUid;
   3642         final String callingPackage;
   3643         final Intent intent;
   3644         final int userId;
   3645         synchronized (this) {
   3646             task = recentTaskForIdLocked(taskId);
   3647             if (task == null) {
   3648                 throw new IllegalArgumentException("Task " + taskId + " not found.");
   3649             }
   3650             if (task.getRootActivity() != null) {
   3651                 moveTaskToFrontLocked(task.taskId, 0, null);
   3652                 return ActivityManager.START_TASK_TO_FRONT;
   3653             }
   3654             callingUid = task.mCallingUid;
   3655             callingPackage = task.mCallingPackage;
   3656             intent = task.intent;
   3657             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
   3658             userId = task.userId;
   3659         }
   3660         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
   3661                 options, userId, null, task);
   3662     }
   3663 
   3664     final int startActivityInPackage(int uid, String callingPackage,
   3665             Intent intent, String resolvedType, IBinder resultTo,
   3666             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
   3667             IActivityContainer container, TaskRecord inTask) {
   3668 
   3669         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3670                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3671 
   3672         // TODO: Switch to user app stacks here.
   3673         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
   3674                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3675                 null, null, null, options, userId, container, inTask);
   3676         return ret;
   3677     }
   3678 
   3679     @Override
   3680     public final int startActivities(IApplicationThread caller, String callingPackage,
   3681             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   3682             int userId) {
   3683         enforceNotIsolatedCaller("startActivities");
   3684         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3685                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3686         // TODO: Switch to user app stacks here.
   3687         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
   3688                 resolvedTypes, resultTo, options, userId);
   3689         return ret;
   3690     }
   3691 
   3692     final int startActivitiesInPackage(int uid, String callingPackage,
   3693             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   3694             Bundle options, int userId) {
   3695 
   3696         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3697                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3698         // TODO: Switch to user app stacks here.
   3699         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   3700                 resultTo, options, userId);
   3701         return ret;
   3702     }
   3703 
   3704     //explicitly remove thd old information in mRecentTasks when removing existing user.
   3705     private void removeRecentTasksForUserLocked(int userId) {
   3706         if(userId <= 0) {
   3707             Slog.i(TAG, "Can't remove recent task on user " + userId);
   3708             return;
   3709         }
   3710 
   3711         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
   3712             TaskRecord tr = mRecentTasks.get(i);
   3713             if (tr.userId == userId) {
   3714                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
   3715                         + " when finishing user" + userId);
   3716                 mRecentTasks.remove(i);
   3717                 tr.removedFromRecents();
   3718             }
   3719         }
   3720 
   3721         // Remove tasks from persistent storage.
   3722         notifyTaskPersisterLocked(null, true);
   3723     }
   3724 
   3725     // Sort by taskId
   3726     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
   3727         @Override
   3728         public int compare(TaskRecord lhs, TaskRecord rhs) {
   3729             return rhs.taskId - lhs.taskId;
   3730         }
   3731     };
   3732 
   3733     // Extract the affiliates of the chain containing mRecentTasks[start].
   3734     private int processNextAffiliateChainLocked(int start) {
   3735         final TaskRecord startTask = mRecentTasks.get(start);
   3736         final int affiliateId = startTask.mAffiliatedTaskId;
   3737 
   3738         // Quick identification of isolated tasks. I.e. those not launched behind.
   3739         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
   3740                 startTask.mNextAffiliate == null) {
   3741             // There is still a slim chance that there are other tasks that point to this task
   3742             // and that the chain is so messed up that this task no longer points to them but
   3743             // the gain of this optimization outweighs the risk.
   3744             startTask.inRecents = true;
   3745             return start + 1;
   3746         }
   3747 
   3748         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
   3749         mTmpRecents.clear();
   3750         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
   3751             final TaskRecord task = mRecentTasks.get(i);
   3752             if (task.mAffiliatedTaskId == affiliateId) {
   3753                 mRecentTasks.remove(i);
   3754                 mTmpRecents.add(task);
   3755             }
   3756         }
   3757 
   3758         // Sort them all by taskId. That is the order they were create in and that order will
   3759         // always be correct.
   3760         Collections.sort(mTmpRecents, mTaskRecordComparator);
   3761 
   3762         // Go through and fix up the linked list.
   3763         // The first one is the end of the chain and has no next.
   3764         final TaskRecord first = mTmpRecents.get(0);
   3765         first.inRecents = true;
   3766         if (first.mNextAffiliate != null) {
   3767             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
   3768             first.setNextAffiliate(null);
   3769             notifyTaskPersisterLocked(first, false);
   3770         }
   3771         // Everything in the middle is doubly linked from next to prev.
   3772         final int tmpSize = mTmpRecents.size();
   3773         for (int i = 0; i < tmpSize - 1; ++i) {
   3774             final TaskRecord next = mTmpRecents.get(i);
   3775             final TaskRecord prev = mTmpRecents.get(i + 1);
   3776             if (next.mPrevAffiliate != prev) {
   3777                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
   3778                         " setting prev=" + prev);
   3779                 next.setPrevAffiliate(prev);
   3780                 notifyTaskPersisterLocked(next, false);
   3781             }
   3782             if (prev.mNextAffiliate != next) {
   3783                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
   3784                         " setting next=" + next);
   3785                 prev.setNextAffiliate(next);
   3786                 notifyTaskPersisterLocked(prev, false);
   3787             }
   3788             prev.inRecents = true;
   3789         }
   3790         // The last one is the beginning of the list and has no prev.
   3791         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
   3792         if (last.mPrevAffiliate != null) {
   3793             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
   3794             last.setPrevAffiliate(null);
   3795             notifyTaskPersisterLocked(last, false);
   3796         }
   3797 
   3798         // Insert the group back into mRecentTasks at start.
   3799         mRecentTasks.addAll(start, mTmpRecents);
   3800 
   3801         // Let the caller know where we left off.
   3802         return start + tmpSize;
   3803     }
   3804 
   3805     /**
   3806      * Update the recent tasks lists: make sure tasks should still be here (their
   3807      * applications / activities still exist), update their availability, fixup ordering
   3808      * of affiliations.
   3809      */
   3810     void cleanupRecentTasksLocked(int userId) {
   3811         if (mRecentTasks == null) {
   3812             // Happens when called from the packagemanager broadcast before boot.
   3813             return;
   3814         }
   3815 
   3816         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
   3817         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
   3818         final IPackageManager pm = AppGlobals.getPackageManager();
   3819         final ActivityInfo dummyAct = new ActivityInfo();
   3820         final ApplicationInfo dummyApp = new ApplicationInfo();
   3821 
   3822         int N = mRecentTasks.size();
   3823 
   3824         int[] users = userId == UserHandle.USER_ALL
   3825                 ? getUsersLocked() : new int[] { userId };
   3826         for (int user : users) {
   3827             for (int i = 0; i < N; i++) {
   3828                 TaskRecord task = mRecentTasks.get(i);
   3829                 if (task.userId != user) {
   3830                     // Only look at tasks for the user ID of interest.
   3831                     continue;
   3832                 }
   3833                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
   3834                     // This situation is broken, and we should just get rid of it now.
   3835                     mRecentTasks.remove(i);
   3836                     task.removedFromRecents();
   3837                     i--;
   3838                     N--;
   3839                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
   3840                     continue;
   3841                 }
   3842                 // Check whether this activity is currently available.
   3843                 if (task.realActivity != null) {
   3844                     ActivityInfo ai = availActCache.get(task.realActivity);
   3845                     if (ai == null) {
   3846                         try {
   3847                             ai = pm.getActivityInfo(task.realActivity,
   3848                                     PackageManager.GET_UNINSTALLED_PACKAGES
   3849                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
   3850                         } catch (RemoteException e) {
   3851                             // Will never happen.
   3852                             continue;
   3853                         }
   3854                         if (ai == null) {
   3855                             ai = dummyAct;
   3856                         }
   3857                         availActCache.put(task.realActivity, ai);
   3858                     }
   3859                     if (ai == dummyAct) {
   3860                         // This could be either because the activity no longer exists, or the
   3861                         // app is temporarily gone.  For the former we want to remove the recents
   3862                         // entry; for the latter we want to mark it as unavailable.
   3863                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
   3864                         if (app == null) {
   3865                             try {
   3866                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
   3867                                         PackageManager.GET_UNINSTALLED_PACKAGES
   3868                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
   3869                             } catch (RemoteException e) {
   3870                                 // Will never happen.
   3871                                 continue;
   3872                             }
   3873                             if (app == null) {
   3874                                 app = dummyApp;
   3875                             }
   3876                             availAppCache.put(task.realActivity.getPackageName(), app);
   3877                         }
   3878                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   3879                             // Doesn't exist any more!  Good-bye.
   3880                             mRecentTasks.remove(i);
   3881                             task.removedFromRecents();
   3882                             i--;
   3883                             N--;
   3884                             Slog.w(TAG, "Removing no longer valid recent: " + task);
   3885                             continue;
   3886                         } else {
   3887                             // Otherwise just not available for now.
   3888                             if (task.isAvailable) {
   3889                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   3890                                         + task);
   3891                             }
   3892                             task.isAvailable = false;
   3893                         }
   3894                     } else {
   3895                         if (!ai.enabled || !ai.applicationInfo.enabled
   3896                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   3897                             if (task.isAvailable) {
   3898                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   3899                                         + task + " (enabled=" + ai.enabled + "/"
   3900                                         + ai.applicationInfo.enabled +  " flags="
   3901                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
   3902                             }
   3903                             task.isAvailable = false;
   3904                         } else {
   3905                             if (!task.isAvailable) {
   3906                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
   3907                                         + task);
   3908                             }
   3909                             task.isAvailable = true;
   3910                         }
   3911                     }
   3912                 }
   3913             }
   3914         }
   3915 
   3916         // Verify the affiliate chain for each task.
   3917         for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
   3918         }
   3919 
   3920         mTmpRecents.clear();
   3921         // mRecentTasks is now in sorted, affiliated order.
   3922     }
   3923 
   3924     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
   3925         int N = mRecentTasks.size();
   3926         TaskRecord top = task;
   3927         int topIndex = taskIndex;
   3928         while (top.mNextAffiliate != null && topIndex > 0) {
   3929             top = top.mNextAffiliate;
   3930             topIndex--;
   3931         }
   3932         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
   3933                 + topIndex + " from intial " + taskIndex);
   3934         // Find the end of the chain, doing a sanity check along the way.
   3935         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
   3936         int endIndex = topIndex;
   3937         TaskRecord prev = top;
   3938         while (endIndex < N) {
   3939             TaskRecord cur = mRecentTasks.get(endIndex);
   3940             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
   3941                     + endIndex + " " + cur);
   3942             if (cur == top) {
   3943                 // Verify start of the chain.
   3944                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
   3945                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3946                             + ": first task has next affiliate: " + prev);
   3947                     sane = false;
   3948                     break;
   3949                 }
   3950             } else {
   3951                 // Verify middle of the chain's next points back to the one before.
   3952                 if (cur.mNextAffiliate != prev
   3953                         || cur.mNextAffiliateTaskId != prev.taskId) {
   3954                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3955                             + ": middle task " + cur + " @" + endIndex
   3956                             + " has bad next affiliate "
   3957                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
   3958                             + ", expected " + prev);
   3959                     sane = false;
   3960                     break;
   3961                 }
   3962             }
   3963             if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
   3964                 // Chain ends here.
   3965                 if (cur.mPrevAffiliate != null) {
   3966                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3967                             + ": last task " + cur + " has previous affiliate "
   3968                             + cur.mPrevAffiliate);
   3969                     sane = false;
   3970                 }
   3971                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
   3972                 break;
   3973             } else {
   3974                 // Verify middle of the chain's prev points to a valid item.
   3975                 if (cur.mPrevAffiliate == null) {
   3976                     Slog.wtf(TAG, "Bad chain @" + endIndex
   3977                             + ": task " + cur + " has previous affiliate "
   3978                             + cur.mPrevAffiliate + " but should be id "
   3979                             + cur.mPrevAffiliate);
   3980                     sane = false;
   3981                     break;
   3982                 }
   3983             }
   3984             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
   3985                 Slog.wtf(TAG, "Bad chain @" + endIndex
   3986                         + ": task " + cur + " has affiliated id "
   3987                         + cur.mAffiliatedTaskId + " but should be "
   3988                         + task.mAffiliatedTaskId);
   3989                 sane = false;
   3990                 break;
   3991             }
   3992             prev = cur;
   3993             endIndex++;
   3994             if (endIndex >= N) {
   3995                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
   3996                         + ": last task " + prev);
   3997                 sane = false;
   3998                 break;
   3999             }
   4000         }
   4001         if (sane) {
   4002             if (endIndex < taskIndex) {
   4003                 Slog.wtf(TAG, "Bad chain @" + endIndex
   4004                         + ": did not extend to task " + task + " @" + taskIndex);
   4005                 sane = false;
   4006             }
   4007         }
   4008         if (sane) {
   4009             // All looks good, we can just move all of the affiliated tasks
   4010             // to the top.
   4011             for (int i=topIndex; i<=endIndex; i++) {
   4012                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
   4013                         + " from " + i + " to " + (i-topIndex));
   4014                 TaskRecord cur = mRecentTasks.remove(i);
   4015                 mRecentTasks.add(i-topIndex, cur);
   4016             }
   4017             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
   4018                     + " to " + endIndex);
   4019             return true;
   4020         }
   4021 
   4022         // Whoops, couldn't do it.
   4023         return false;
   4024     }
   4025 
   4026     final void addRecentTaskLocked(TaskRecord task) {
   4027         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
   4028                 || task.mNextAffiliateTaskId != INVALID_TASK_ID
   4029                 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
   4030 
   4031         int N = mRecentTasks.size();
   4032         // Quick case: check if the top-most recent task is the same.
   4033         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
   4034             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
   4035             return;
   4036         }
   4037         // Another quick case: check if this is part of a set of affiliated
   4038         // tasks that are at the top.
   4039         if (isAffiliated && N > 0 && task.inRecents
   4040                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
   4041             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
   4042                     + " at top when adding " + task);
   4043             return;
   4044         }
   4045         // Another quick case: never add voice sessions.
   4046         if (task.voiceSession != null) {
   4047             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
   4048             return;
   4049         }
   4050 
   4051         boolean needAffiliationFix = false;
   4052 
   4053         // Slightly less quick case: the task is already in recents, so all we need
   4054         // to do is move it.
   4055         if (task.inRecents) {
   4056             int taskIndex = mRecentTasks.indexOf(task);
   4057             if (taskIndex >= 0) {
   4058                 if (!isAffiliated) {
   4059                     // Simple case: this is not an affiliated task, so we just move it to the front.
   4060                     mRecentTasks.remove(taskIndex);
   4061                     mRecentTasks.add(0, task);
   4062                     notifyTaskPersisterLocked(task, false);
   4063                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
   4064                             + " from " + taskIndex);
   4065                     return;
   4066                 } else {
   4067                     // More complicated: need to keep all affiliated tasks together.
   4068                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4069                         // All went well.
   4070                         return;
   4071                     }
   4072 
   4073                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4074                     // everything and then go through our general path of adding a new task.
   4075                     needAffiliationFix = true;
   4076                 }
   4077             } else {
   4078                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
   4079                 needAffiliationFix = true;
   4080             }
   4081         }
   4082 
   4083         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
   4084         trimRecentsForTaskLocked(task, true);
   4085 
   4086         N = mRecentTasks.size();
   4087         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
   4088             final TaskRecord tr = mRecentTasks.remove(N - 1);
   4089             tr.removedFromRecents();
   4090             N--;
   4091         }
   4092         task.inRecents = true;
   4093         if (!isAffiliated || needAffiliationFix) {
   4094             // If this is a simple non-affiliated task, or we had some failure trying to
   4095             // handle it as part of an affilated task, then just place it at the top.
   4096             mRecentTasks.add(0, task);
   4097         } else if (isAffiliated) {
   4098             // If this is a new affiliated task, then move all of the affiliated tasks
   4099             // to the front and insert this new one.
   4100             TaskRecord other = task.mNextAffiliate;
   4101             if (other == null) {
   4102                 other = task.mPrevAffiliate;
   4103             }
   4104             if (other != null) {
   4105                 int otherIndex = mRecentTasks.indexOf(other);
   4106                 if (otherIndex >= 0) {
   4107                     // Insert new task at appropriate location.
   4108                     int taskIndex;
   4109                     if (other == task.mNextAffiliate) {
   4110                         // We found the index of our next affiliation, which is who is
   4111                         // before us in the list, so add after that point.
   4112                         taskIndex = otherIndex+1;
   4113                     } else {
   4114                         // We found the index of our previous affiliation, which is who is
   4115                         // after us in the list, so add at their position.
   4116                         taskIndex = otherIndex;
   4117                     }
   4118                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
   4119                             + taskIndex + ": " + task);
   4120                     mRecentTasks.add(taskIndex, task);
   4121 
   4122                     // Now move everything to the front.
   4123                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4124                         // All went well.
   4125                         return;
   4126                     }
   4127 
   4128                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4129                     // everything and then go through our general path of adding a new task.
   4130                     needAffiliationFix = true;
   4131                 } else {
   4132                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
   4133                             + other);
   4134                     needAffiliationFix = true;
   4135                 }
   4136             } else {
   4137                 if (DEBUG_RECENTS) Slog.d(TAG,
   4138                         "addRecent: adding affiliated task without next/prev:" + task);
   4139                 needAffiliationFix = true;
   4140             }
   4141         }
   4142         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
   4143 
   4144         if (needAffiliationFix) {
   4145             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
   4146             cleanupRecentTasksLocked(task.userId);
   4147         }
   4148     }
   4149 
   4150     /**
   4151      * If needed, remove oldest existing entries in recents that are for the same kind
   4152      * of task as the given one.
   4153      */
   4154     int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
   4155         int N = mRecentTasks.size();
   4156         final Intent intent = task.intent;
   4157         final boolean document = intent != null && intent.isDocument();
   4158 
   4159         int maxRecents = task.maxRecents - 1;
   4160         for (int i=0; i<N; i++) {
   4161             final TaskRecord tr = mRecentTasks.get(i);
   4162             if (task != tr) {
   4163                 if (task.userId != tr.userId) {
   4164                     continue;
   4165                 }
   4166                 if (i > MAX_RECENT_BITMAPS) {
   4167                     tr.freeLastThumbnail();
   4168                 }
   4169                 final Intent trIntent = tr.intent;
   4170                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
   4171                     (intent == null || !intent.filterEquals(trIntent))) {
   4172                     continue;
   4173                 }
   4174                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
   4175                 if (document && trIsDocument) {
   4176                     // These are the same document activity (not necessarily the same doc).
   4177                     if (maxRecents > 0) {
   4178                         --maxRecents;
   4179                         continue;
   4180                     }
   4181                     // Hit the maximum number of documents for this task. Fall through
   4182                     // and remove this document from recents.
   4183                 } else if (document || trIsDocument) {
   4184                     // Only one of these is a document. Not the droid we're looking for.
   4185                     continue;
   4186                 }
   4187             }
   4188 
   4189             if (!doTrim) {
   4190                 // If the caller is not actually asking for a trim, just tell them we reached
   4191                 // a point where the trim would happen.
   4192                 return i;
   4193             }
   4194 
   4195             // Either task and tr are the same or, their affinities match or their intents match
   4196             // and neither of them is a document, or they are documents using the same activity
   4197             // and their maxRecents has been reached.
   4198             tr.disposeThumbnail();
   4199             mRecentTasks.remove(i);
   4200             if (task != tr) {
   4201                 tr.removedFromRecents();
   4202             }
   4203             i--;
   4204             N--;
   4205             if (task.intent == null) {
   4206                 // If the new recent task we are adding is not fully
   4207                 // specified, then replace it with the existing recent task.
   4208                 task = tr;
   4209             }
   4210             notifyTaskPersisterLocked(tr, false);
   4211         }
   4212 
   4213         return -1;
   4214     }
   4215 
   4216     @Override
   4217     public void reportActivityFullyDrawn(IBinder token) {
   4218         synchronized (this) {
   4219             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4220             if (r == null) {
   4221                 return;
   4222             }
   4223             r.reportFullyDrawnLocked();
   4224         }
   4225     }
   4226 
   4227     @Override
   4228     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4229         synchronized (this) {
   4230             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4231             if (r == null) {
   4232                 return;
   4233             }
   4234             final long origId = Binder.clearCallingIdentity();
   4235             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4236             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4237                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4238             if (config != null) {
   4239                 r.frozenBeforeDestroy = true;
   4240                 if (!updateConfigurationLocked(config, r, false, false)) {
   4241                     mStackSupervisor.resumeTopActivitiesLocked();
   4242                 }
   4243             }
   4244             Binder.restoreCallingIdentity(origId);
   4245         }
   4246     }
   4247 
   4248     @Override
   4249     public int getRequestedOrientation(IBinder token) {
   4250         synchronized (this) {
   4251             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4252             if (r == null) {
   4253                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4254             }
   4255             return mWindowManager.getAppOrientation(r.appToken);
   4256         }
   4257     }
   4258 
   4259     /**
   4260      * This is the internal entry point for handling Activity.finish().
   4261      *
   4262      * @param token The Binder token referencing the Activity we want to finish.
   4263      * @param resultCode Result code, if any, from this Activity.
   4264      * @param resultData Result data (Intent), if any, from this Activity.
   4265      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
   4266      *            the root Activity in the task.
   4267      *
   4268      * @return Returns true if the activity successfully finished, or false if it is still running.
   4269      */
   4270     @Override
   4271     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4272             boolean finishTask) {
   4273         // Refuse possible leaked file descriptors
   4274         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4275             throw new IllegalArgumentException("File descriptors passed in Intent");
   4276         }
   4277 
   4278         synchronized(this) {
   4279             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4280             if (r == null) {
   4281                 return true;
   4282             }
   4283             // Keep track of the root activity of the task before we finish it
   4284             TaskRecord tr = r.task;
   4285             ActivityRecord rootR = tr.getRootActivity();
   4286             if (rootR == null) {
   4287                 Slog.w(TAG, "Finishing task with all activities already finished");
   4288             }
   4289             // Do not allow task to finish in Lock Task mode.
   4290             if (tr == mStackSupervisor.mLockTaskModeTask) {
   4291                 if (rootR == r) {
   4292                     Slog.i(TAG, "Not finishing task in lock task mode");
   4293                     mStackSupervisor.showLockTaskToast();
   4294                     return false;
   4295                 }
   4296             }
   4297             if (mController != null) {
   4298                 // Find the first activity that is not finishing.
   4299                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4300                 if (next != null) {
   4301                     // ask watcher if this is allowed
   4302                     boolean resumeOK = true;
   4303                     try {
   4304                         resumeOK = mController.activityResuming(next.packageName);
   4305                     } catch (RemoteException e) {
   4306                         mController = null;
   4307                         Watchdog.getInstance().setActivityController(null);
   4308                     }
   4309 
   4310                     if (!resumeOK) {
   4311                         Slog.i(TAG, "Not finishing activity because controller resumed");
   4312                         return false;
   4313                     }
   4314                 }
   4315             }
   4316             final long origId = Binder.clearCallingIdentity();
   4317             try {
   4318                 boolean res;
   4319                 if (finishTask && r == rootR) {
   4320                     // If requested, remove the task that is associated to this activity only if it
   4321                     // was the root activity in the task. The result code and data is ignored
   4322                     // because we don't support returning them across task boundaries.
   4323                     res = removeTaskByIdLocked(tr.taskId, false);
   4324                     if (!res) {
   4325                         Slog.i(TAG, "Removing task failed to finish activity");
   4326                     }
   4327                 } else {
   4328                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4329                             resultData, "app-request", true);
   4330                     if (!res) {
   4331                         Slog.i(TAG, "Failed to finish by app-request");
   4332                     }
   4333                 }
   4334                 return res;
   4335             } finally {
   4336                 Binder.restoreCallingIdentity(origId);
   4337             }
   4338         }
   4339     }
   4340 
   4341     @Override
   4342     public final void finishHeavyWeightApp() {
   4343         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4344                 != PackageManager.PERMISSION_GRANTED) {
   4345             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4346                     + Binder.getCallingPid()
   4347                     + ", uid=" + Binder.getCallingUid()
   4348                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4349             Slog.w(TAG, msg);
   4350             throw new SecurityException(msg);
   4351         }
   4352 
   4353         synchronized(this) {
   4354             if (mHeavyWeightProcess == null) {
   4355                 return;
   4356             }
   4357 
   4358             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   4359                     mHeavyWeightProcess.activities);
   4360             for (int i=0; i<activities.size(); i++) {
   4361                 ActivityRecord r = activities.get(i);
   4362                 if (!r.finishing) {
   4363                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4364                             null, "finish-heavy", true);
   4365                 }
   4366             }
   4367 
   4368             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4369                     mHeavyWeightProcess.userId, 0));
   4370             mHeavyWeightProcess = null;
   4371         }
   4372     }
   4373 
   4374     @Override
   4375     public void crashApplication(int uid, int initialPid, String packageName,
   4376             String message) {
   4377         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4378                 != PackageManager.PERMISSION_GRANTED) {
   4379             String msg = "Permission Denial: crashApplication() from pid="
   4380                     + Binder.getCallingPid()
   4381                     + ", uid=" + Binder.getCallingUid()
   4382                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4383             Slog.w(TAG, msg);
   4384             throw new SecurityException(msg);
   4385         }
   4386 
   4387         synchronized(this) {
   4388             ProcessRecord proc = null;
   4389 
   4390             // Figure out which process to kill.  We don't trust that initialPid
   4391             // still has any relation to current pids, so must scan through the
   4392             // list.
   4393             synchronized (mPidsSelfLocked) {
   4394                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   4395                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   4396                     if (p.uid != uid) {
   4397                         continue;
   4398                     }
   4399                     if (p.pid == initialPid) {
   4400                         proc = p;
   4401                         break;
   4402                     }
   4403                     if (p.pkgList.containsKey(packageName)) {
   4404                         proc = p;
   4405                     }
   4406                 }
   4407             }
   4408 
   4409             if (proc == null) {
   4410                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   4411                         + " initialPid=" + initialPid
   4412                         + " packageName=" + packageName);
   4413                 return;
   4414             }
   4415 
   4416             if (proc.thread != null) {
   4417                 if (proc.pid == Process.myPid()) {
   4418                     Log.w(TAG, "crashApplication: trying to crash self!");
   4419                     return;
   4420                 }
   4421                 long ident = Binder.clearCallingIdentity();
   4422                 try {
   4423                     proc.thread.scheduleCrash(message);
   4424                 } catch (RemoteException e) {
   4425                 }
   4426                 Binder.restoreCallingIdentity(ident);
   4427             }
   4428         }
   4429     }
   4430 
   4431     @Override
   4432     public final void finishSubActivity(IBinder token, String resultWho,
   4433             int requestCode) {
   4434         synchronized(this) {
   4435             final long origId = Binder.clearCallingIdentity();
   4436             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4437             if (r != null) {
   4438                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4439             }
   4440             Binder.restoreCallingIdentity(origId);
   4441         }
   4442     }
   4443 
   4444     @Override
   4445     public boolean finishActivityAffinity(IBinder token) {
   4446         synchronized(this) {
   4447             final long origId = Binder.clearCallingIdentity();
   4448             try {
   4449                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4450 
   4451                 ActivityRecord rootR = r.task.getRootActivity();
   4452                 // Do not allow task to finish in Lock Task mode.
   4453                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
   4454                     if (rootR == r) {
   4455                         mStackSupervisor.showLockTaskToast();
   4456                         return false;
   4457                     }
   4458                 }
   4459                 boolean res = false;
   4460                 if (r != null) {
   4461                     res = r.task.stack.finishActivityAffinityLocked(r);
   4462                 }
   4463                 return res;
   4464             } finally {
   4465                 Binder.restoreCallingIdentity(origId);
   4466             }
   4467         }
   4468     }
   4469 
   4470     @Override
   4471     public void finishVoiceTask(IVoiceInteractionSession session) {
   4472         synchronized(this) {
   4473             final long origId = Binder.clearCallingIdentity();
   4474             try {
   4475                 mStackSupervisor.finishVoiceTask(session);
   4476             } finally {
   4477                 Binder.restoreCallingIdentity(origId);
   4478             }
   4479         }
   4480 
   4481     }
   4482 
   4483     @Override
   4484     public boolean releaseActivityInstance(IBinder token) {
   4485         synchronized(this) {
   4486             final long origId = Binder.clearCallingIdentity();
   4487             try {
   4488                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4489                 if (r.task == null || r.task.stack == null) {
   4490                     return false;
   4491                 }
   4492                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   4493             } finally {
   4494                 Binder.restoreCallingIdentity(origId);
   4495             }
   4496         }
   4497     }
   4498 
   4499     @Override
   4500     public void releaseSomeActivities(IApplicationThread appInt) {
   4501         synchronized(this) {
   4502             final long origId = Binder.clearCallingIdentity();
   4503             try {
   4504                 ProcessRecord app = getRecordForAppLocked(appInt);
   4505                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   4506             } finally {
   4507                 Binder.restoreCallingIdentity(origId);
   4508             }
   4509         }
   4510     }
   4511 
   4512     @Override
   4513     public boolean willActivityBeVisible(IBinder token) {
   4514         synchronized(this) {
   4515             ActivityStack stack = ActivityRecord.getStackLocked(token);
   4516             if (stack != null) {
   4517                 return stack.willActivityBeVisibleLocked(token);
   4518             }
   4519             return false;
   4520         }
   4521     }
   4522 
   4523     @Override
   4524     public void overridePendingTransition(IBinder token, String packageName,
   4525             int enterAnim, int exitAnim) {
   4526         synchronized(this) {
   4527             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   4528             if (self == null) {
   4529                 return;
   4530             }
   4531 
   4532             final long origId = Binder.clearCallingIdentity();
   4533 
   4534             if (self.state == ActivityState.RESUMED
   4535                     || self.state == ActivityState.PAUSING) {
   4536                 mWindowManager.overridePendingAppTransition(packageName,
   4537                         enterAnim, exitAnim, null);
   4538             }
   4539 
   4540             Binder.restoreCallingIdentity(origId);
   4541         }
   4542     }
   4543 
   4544     /**
   4545      * Main function for removing an existing process from the activity manager
   4546      * as a result of that process going away.  Clears out all connections
   4547      * to the process.
   4548      */
   4549     private final void handleAppDiedLocked(ProcessRecord app,
   4550             boolean restarting, boolean allowRestart) {
   4551         int pid = app.pid;
   4552         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   4553         if (!kept && !restarting) {
   4554             removeLruProcessLocked(app);
   4555             if (pid > 0) {
   4556                 ProcessList.remove(pid);
   4557             }
   4558         }
   4559 
   4560         if (mProfileProc == app) {
   4561             clearProfilerLocked();
   4562         }
   4563 
   4564         // Remove this application's activities from active lists.
   4565         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   4566 
   4567         app.activities.clear();
   4568 
   4569         if (app.instrumentationClass != null) {
   4570             Slog.w(TAG, "Crash of app " + app.processName
   4571                   + " running instrumentation " + app.instrumentationClass);
   4572             Bundle info = new Bundle();
   4573             info.putString("shortMsg", "Process crashed.");
   4574             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   4575         }
   4576 
   4577         if (!restarting) {
   4578             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
   4579                 // If there was nothing to resume, and we are not already
   4580                 // restarting this process, but there is a visible activity that
   4581                 // is hosted by the process...  then make sure all visible
   4582                 // activities are running, taking care of restarting this
   4583                 // process.
   4584                 if (hasVisibleActivities) {
   4585                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   4586                 }
   4587             }
   4588         }
   4589     }
   4590 
   4591     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   4592         IBinder threadBinder = thread.asBinder();
   4593         // Find the application record.
   4594         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4595             ProcessRecord rec = mLruProcesses.get(i);
   4596             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   4597                 return i;
   4598             }
   4599         }
   4600         return -1;
   4601     }
   4602 
   4603     final ProcessRecord getRecordForAppLocked(
   4604             IApplicationThread thread) {
   4605         if (thread == null) {
   4606             return null;
   4607         }
   4608 
   4609         int appIndex = getLRURecordIndexForAppLocked(thread);
   4610         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   4611     }
   4612 
   4613     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   4614         // If there are no longer any background processes running,
   4615         // and the app that died was not running instrumentation,
   4616         // then tell everyone we are now low on memory.
   4617         boolean haveBg = false;
   4618         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4619             ProcessRecord rec = mLruProcesses.get(i);
   4620             if (rec.thread != null
   4621                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   4622                 haveBg = true;
   4623                 break;
   4624             }
   4625         }
   4626 
   4627         if (!haveBg) {
   4628             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   4629             if (doReport) {
   4630                 long now = SystemClock.uptimeMillis();
   4631                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   4632                     doReport = false;
   4633                 } else {
   4634                     mLastMemUsageReportTime = now;
   4635                 }
   4636             }
   4637             final ArrayList<ProcessMemInfo> memInfos
   4638                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   4639             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   4640             long now = SystemClock.uptimeMillis();
   4641             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4642                 ProcessRecord rec = mLruProcesses.get(i);
   4643                 if (rec == dyingProc || rec.thread == null) {
   4644                     continue;
   4645                 }
   4646                 if (doReport) {
   4647                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   4648                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   4649                 }
   4650                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   4651                     // The low memory report is overriding any current
   4652                     // state for a GC request.  Make sure to do
   4653                     // heavy/important/visible/foreground processes first.
   4654                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   4655                         rec.lastRequestedGc = 0;
   4656                     } else {
   4657                         rec.lastRequestedGc = rec.lastLowMemory;
   4658                     }
   4659                     rec.reportLowMemory = true;
   4660                     rec.lastLowMemory = now;
   4661                     mProcessesToGc.remove(rec);
   4662                     addProcessToGcListLocked(rec);
   4663                 }
   4664             }
   4665             if (doReport) {
   4666                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   4667                 mHandler.sendMessage(msg);
   4668             }
   4669             scheduleAppGcsLocked();
   4670         }
   4671     }
   4672 
   4673     final void appDiedLocked(ProcessRecord app) {
   4674        appDiedLocked(app, app.pid, app.thread);
   4675     }
   4676 
   4677     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
   4678         // First check if this ProcessRecord is actually active for the pid.
   4679         synchronized (mPidsSelfLocked) {
   4680             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   4681             if (curProc != app) {
   4682                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   4683                 return;
   4684             }
   4685         }
   4686 
   4687         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   4688         synchronized (stats) {
   4689             stats.noteProcessDiedLocked(app.info.uid, pid);
   4690         }
   4691 
   4692         if (!app.killed) {
   4693             Process.killProcessQuiet(pid);
   4694             Process.killProcessGroup(app.info.uid, pid);
   4695             app.killed = true;
   4696         }
   4697 
   4698         // Clean up already done if the process has been re-started.
   4699         if (app.pid == pid && app.thread != null &&
   4700                 app.thread.asBinder() == thread.asBinder()) {
   4701             boolean doLowMem = app.instrumentationClass == null;
   4702             boolean doOomAdj = doLowMem;
   4703             if (!app.killedByAm) {
   4704                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4705                         + ") has died");
   4706                 mAllowLowerMemLevel = true;
   4707             } else {
   4708                 // Note that we always want to do oom adj to update our state with the
   4709                 // new number of procs.
   4710                 mAllowLowerMemLevel = false;
   4711                 doLowMem = false;
   4712             }
   4713             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4714             if (DEBUG_CLEANUP) Slog.v(
   4715                 TAG, "Dying app: " + app + ", pid: " + pid
   4716                 + ", thread: " + thread.asBinder());
   4717             handleAppDiedLocked(app, false, true);
   4718 
   4719             if (doOomAdj) {
   4720                 updateOomAdjLocked();
   4721             }
   4722             if (doLowMem) {
   4723                 doLowMemReportIfNeededLocked(app);
   4724             }
   4725         } else if (app.pid != pid) {
   4726             // A new process has already been started.
   4727             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4728                     + ") has died and restarted (pid " + app.pid + ").");
   4729             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4730         } else if (DEBUG_PROCESSES) {
   4731             Slog.d(TAG, "Received spurious death notification for thread "
   4732                     + thread.asBinder());
   4733         }
   4734     }
   4735 
   4736     /**
   4737      * If a stack trace dump file is configured, dump process stack traces.
   4738      * @param clearTraces causes the dump file to be erased prior to the new
   4739      *    traces being written, if true; when false, the new traces will be
   4740      *    appended to any existing file content.
   4741      * @param firstPids of dalvik VM processes to dump stack traces for first
   4742      * @param lastPids of dalvik VM processes to dump stack traces for last
   4743      * @param nativeProcs optional list of native process names to dump stack crawls
   4744      * @return file containing stack traces, or null if no dump file is configured
   4745      */
   4746     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   4747             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4748         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4749         if (tracesPath == null || tracesPath.length() == 0) {
   4750             return null;
   4751         }
   4752 
   4753         File tracesFile = new File(tracesPath);
   4754         try {
   4755             File tracesDir = tracesFile.getParentFile();
   4756             if (!tracesDir.exists()) {
   4757                 tracesDir.mkdirs();
   4758                 if (!SELinux.restorecon(tracesDir)) {
   4759                     return null;
   4760                 }
   4761             }
   4762             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4763 
   4764             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   4765             tracesFile.createNewFile();
   4766             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4767         } catch (IOException e) {
   4768             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   4769             return null;
   4770         }
   4771 
   4772         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   4773         return tracesFile;
   4774     }
   4775 
   4776     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   4777             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4778         // Use a FileObserver to detect when traces finish writing.
   4779         // The order of traces is considered important to maintain for legibility.
   4780         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   4781             @Override
   4782             public synchronized void onEvent(int event, String path) { notify(); }
   4783         };
   4784 
   4785         try {
   4786             observer.startWatching();
   4787 
   4788             // First collect all of the stacks of the most important pids.
   4789             if (firstPids != null) {
   4790                 try {
   4791                     int num = firstPids.size();
   4792                     for (int i = 0; i < num; i++) {
   4793                         synchronized (observer) {
   4794                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   4795                             observer.wait(200);  // Wait for write-close, give up after 200msec
   4796                         }
   4797                     }
   4798                 } catch (InterruptedException e) {
   4799                     Slog.wtf(TAG, e);
   4800                 }
   4801             }
   4802 
   4803             // Next collect the stacks of the native pids
   4804             if (nativeProcs != null) {
   4805                 int[] pids = Process.getPidsForCommands(nativeProcs);
   4806                 if (pids != null) {
   4807                     for (int pid : pids) {
   4808                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   4809                     }
   4810                 }
   4811             }
   4812 
   4813             // Lastly, measure CPU usage.
   4814             if (processCpuTracker != null) {
   4815                 processCpuTracker.init();
   4816                 System.gc();
   4817                 processCpuTracker.update();
   4818                 try {
   4819                     synchronized (processCpuTracker) {
   4820                         processCpuTracker.wait(500); // measure over 1/2 second.
   4821                     }
   4822                 } catch (InterruptedException e) {
   4823                 }
   4824                 processCpuTracker.update();
   4825 
   4826                 // We'll take the stack crawls of just the top apps using CPU.
   4827                 final int N = processCpuTracker.countWorkingStats();
   4828                 int numProcs = 0;
   4829                 for (int i=0; i<N && numProcs<5; i++) {
   4830                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   4831                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   4832                         numProcs++;
   4833                         try {
   4834                             synchronized (observer) {
   4835                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   4836                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   4837                             }
   4838                         } catch (InterruptedException e) {
   4839                             Slog.wtf(TAG, e);
   4840                         }
   4841 
   4842                     }
   4843                 }
   4844             }
   4845         } finally {
   4846             observer.stopWatching();
   4847         }
   4848     }
   4849 
   4850     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   4851         if (true || IS_USER_BUILD) {
   4852             return;
   4853         }
   4854         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4855         if (tracesPath == null || tracesPath.length() == 0) {
   4856             return;
   4857         }
   4858 
   4859         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   4860         StrictMode.allowThreadDiskWrites();
   4861         try {
   4862             final File tracesFile = new File(tracesPath);
   4863             final File tracesDir = tracesFile.getParentFile();
   4864             final File tracesTmp = new File(tracesDir, "__tmp__");
   4865             try {
   4866                 if (!tracesDir.exists()) {
   4867                     tracesDir.mkdirs();
   4868                     if (!SELinux.restorecon(tracesDir.getPath())) {
   4869                         return;
   4870                     }
   4871                 }
   4872                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4873 
   4874                 if (tracesFile.exists()) {
   4875                     tracesTmp.delete();
   4876                     tracesFile.renameTo(tracesTmp);
   4877                 }
   4878                 StringBuilder sb = new StringBuilder();
   4879                 Time tobj = new Time();
   4880                 tobj.set(System.currentTimeMillis());
   4881                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   4882                 sb.append(": ");
   4883                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   4884                 sb.append(" since ");
   4885                 sb.append(msg);
   4886                 FileOutputStream fos = new FileOutputStream(tracesFile);
   4887                 fos.write(sb.toString().getBytes());
   4888                 if (app == null) {
   4889                     fos.write("\n*** No application process!".getBytes());
   4890                 }
   4891                 fos.close();
   4892                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4893             } catch (IOException e) {
   4894                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   4895                 return;
   4896             }
   4897 
   4898             if (app != null) {
   4899                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   4900                 firstPids.add(app.pid);
   4901                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   4902             }
   4903 
   4904             File lastTracesFile = null;
   4905             File curTracesFile = null;
   4906             for (int i=9; i>=0; i--) {
   4907                 String name = String.format(Locale.US, "slow%02d.txt", i);
   4908                 curTracesFile = new File(tracesDir, name);
   4909                 if (curTracesFile.exists()) {
   4910                     if (lastTracesFile != null) {
   4911                         curTracesFile.renameTo(lastTracesFile);
   4912                     } else {
   4913                         curTracesFile.delete();
   4914                     }
   4915                 }
   4916                 lastTracesFile = curTracesFile;
   4917             }
   4918             tracesFile.renameTo(curTracesFile);
   4919             if (tracesTmp.exists()) {
   4920                 tracesTmp.renameTo(tracesFile);
   4921             }
   4922         } finally {
   4923             StrictMode.setThreadPolicy(oldPolicy);
   4924         }
   4925     }
   4926 
   4927     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   4928             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   4929         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   4930         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   4931 
   4932         if (mController != null) {
   4933             try {
   4934                 // 0 == continue, -1 = kill process immediately
   4935                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   4936                 if (res < 0 && app.pid != MY_PID) {
   4937                     app.kill("anr", true);
   4938                 }
   4939             } catch (RemoteException e) {
   4940                 mController = null;
   4941                 Watchdog.getInstance().setActivityController(null);
   4942             }
   4943         }
   4944 
   4945         long anrTime = SystemClock.uptimeMillis();
   4946         if (MONITOR_CPU_USAGE) {
   4947             updateCpuStatsNow();
   4948         }
   4949 
   4950         synchronized (this) {
   4951             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   4952             if (mShuttingDown) {
   4953                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   4954                 return;
   4955             } else if (app.notResponding) {
   4956                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   4957                 return;
   4958             } else if (app.crashing) {
   4959                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   4960                 return;
   4961             }
   4962 
   4963             // In case we come through here for the same app before completing
   4964             // this one, mark as anring now so we will bail out.
   4965             app.notResponding = true;
   4966 
   4967             // Log the ANR to the event log.
   4968             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   4969                     app.processName, app.info.flags, annotation);
   4970 
   4971             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   4972             firstPids.add(app.pid);
   4973 
   4974             int parentPid = app.pid;
   4975             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   4976             if (parentPid != app.pid) firstPids.add(parentPid);
   4977 
   4978             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   4979 
   4980             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   4981                 ProcessRecord r = mLruProcesses.get(i);
   4982                 if (r != null && r.thread != null) {
   4983                     int pid = r.pid;
   4984                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   4985                         if (r.persistent) {
   4986                             firstPids.add(pid);
   4987                         } else {
   4988                             lastPids.put(pid, Boolean.TRUE);
   4989                         }
   4990                     }
   4991                 }
   4992             }
   4993         }
   4994 
   4995         // Log the ANR to the main log.
   4996         StringBuilder info = new StringBuilder();
   4997         info.setLength(0);
   4998         info.append("ANR in ").append(app.processName);
   4999         if (activity != null && activity.shortComponentName != null) {
   5000             info.append(" (").append(activity.shortComponentName).append(")");
   5001         }
   5002         info.append("\n");
   5003         info.append("PID: ").append(app.pid).append("\n");
   5004         if (annotation != null) {
   5005             info.append("Reason: ").append(annotation).append("\n");
   5006         }
   5007         if (parent != null && parent != activity) {
   5008             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   5009         }
   5010 
   5011         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
   5012 
   5013         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
   5014                 NATIVE_STACKS_OF_INTEREST);
   5015 
   5016         String cpuInfo = null;
   5017         if (MONITOR_CPU_USAGE) {
   5018             updateCpuStatsNow();
   5019             synchronized (mProcessCpuTracker) {
   5020                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
   5021             }
   5022             info.append(processCpuTracker.printCurrentLoad());
   5023             info.append(cpuInfo);
   5024         }
   5025 
   5026         info.append(processCpuTracker.printCurrentState(anrTime));
   5027 
   5028         Slog.e(TAG, info.toString());
   5029         if (tracesFile == null) {
   5030             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   5031             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   5032         }
   5033 
   5034         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   5035                 cpuInfo, tracesFile, null);
   5036 
   5037         if (mController != null) {
   5038             try {
   5039                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   5040                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   5041                 if (res != 0) {
   5042                     if (res < 0 && app.pid != MY_PID) {
   5043                         app.kill("anr", true);
   5044                     } else {
   5045                         synchronized (this) {
   5046                             mServices.scheduleServiceTimeoutLocked(app);
   5047                         }
   5048                     }
   5049                     return;
   5050                 }
   5051             } catch (RemoteException e) {
   5052                 mController = null;
   5053                 Watchdog.getInstance().setActivityController(null);
   5054             }
   5055         }
   5056 
   5057         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   5058         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   5059                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   5060 
   5061         synchronized (this) {
   5062             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
   5063 
   5064             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   5065                 app.kill("bg anr", true);
   5066                 return;
   5067             }
   5068 
   5069             // Set the app's notResponding state, and look up the errorReportReceiver
   5070             makeAppNotRespondingLocked(app,
   5071                     activity != null ? activity.shortComponentName : null,
   5072                     annotation != null ? "ANR " + annotation : "ANR",
   5073                     info.toString());
   5074 
   5075             // Bring up the infamous App Not Responding dialog
   5076             Message msg = Message.obtain();
   5077             HashMap<String, Object> map = new HashMap<String, Object>();
   5078             msg.what = SHOW_NOT_RESPONDING_MSG;
   5079             msg.obj = map;
   5080             msg.arg1 = aboveSystem ? 1 : 0;
   5081             map.put("app", app);
   5082             if (activity != null) {
   5083                 map.put("activity", activity);
   5084             }
   5085 
   5086             mHandler.sendMessage(msg);
   5087         }
   5088     }
   5089 
   5090     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5091         if (!mLaunchWarningShown) {
   5092             mLaunchWarningShown = true;
   5093             mHandler.post(new Runnable() {
   5094                 @Override
   5095                 public void run() {
   5096                     synchronized (ActivityManagerService.this) {
   5097                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5098                         d.show();
   5099                         mHandler.postDelayed(new Runnable() {
   5100                             @Override
   5101                             public void run() {
   5102                                 synchronized (ActivityManagerService.this) {
   5103                                     d.dismiss();
   5104                                     mLaunchWarningShown = false;
   5105                                 }
   5106                             }
   5107                         }, 4000);
   5108                     }
   5109                 }
   5110             });
   5111         }
   5112     }
   5113 
   5114     @Override
   5115     public boolean clearApplicationUserData(final String packageName,
   5116             final IPackageDataObserver observer, int userId) {
   5117         enforceNotIsolatedCaller("clearApplicationUserData");
   5118         int uid = Binder.getCallingUid();
   5119         int pid = Binder.getCallingPid();
   5120         userId = handleIncomingUser(pid, uid,
   5121                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5122         long callingId = Binder.clearCallingIdentity();
   5123         try {
   5124             IPackageManager pm = AppGlobals.getPackageManager();
   5125             int pkgUid = -1;
   5126             synchronized(this) {
   5127                 try {
   5128                     pkgUid = pm.getPackageUid(packageName, userId);
   5129                 } catch (RemoteException e) {
   5130                 }
   5131                 if (pkgUid == -1) {
   5132                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5133                     if (observer != null) {
   5134                         try {
   5135                             observer.onRemoveCompleted(packageName, false);
   5136                         } catch (RemoteException e) {
   5137                             Slog.i(TAG, "Observer no longer exists.");
   5138                         }
   5139                     }
   5140                     return false;
   5141                 }
   5142                 if (uid == pkgUid || checkComponentPermission(
   5143                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5144                         pid, uid, -1, true)
   5145                         == PackageManager.PERMISSION_GRANTED) {
   5146                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5147                 } else {
   5148                     throw new SecurityException("PID " + pid + " does not have permission "
   5149                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5150                                     + " of package " + packageName);
   5151                 }
   5152 
   5153                 // Remove all tasks match the cleared application package and user
   5154                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5155                     final TaskRecord tr = mRecentTasks.get(i);
   5156                     final String taskPackageName =
   5157                             tr.getBaseIntent().getComponent().getPackageName();
   5158                     if (tr.userId != userId) continue;
   5159                     if (!taskPackageName.equals(packageName)) continue;
   5160                     removeTaskByIdLocked(tr.taskId, false);
   5161                 }
   5162             }
   5163 
   5164             try {
   5165                 // Clear application user data
   5166                 pm.clearApplicationUserData(packageName, observer, userId);
   5167 
   5168                 synchronized(this) {
   5169                     // Remove all permissions granted from/to this package
   5170                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5171                 }
   5172 
   5173                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5174                         Uri.fromParts("package", packageName, null));
   5175                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   5176                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5177                         null, null, 0, null, null, null, false, false, userId);
   5178             } catch (RemoteException e) {
   5179             }
   5180         } finally {
   5181             Binder.restoreCallingIdentity(callingId);
   5182         }
   5183         return true;
   5184     }
   5185 
   5186     @Override
   5187     public void killBackgroundProcesses(final String packageName, int userId) {
   5188         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5189                 != PackageManager.PERMISSION_GRANTED &&
   5190                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5191                         != PackageManager.PERMISSION_GRANTED) {
   5192             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5193                     + Binder.getCallingPid()
   5194                     + ", uid=" + Binder.getCallingUid()
   5195                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5196             Slog.w(TAG, msg);
   5197             throw new SecurityException(msg);
   5198         }
   5199 
   5200         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5201                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5202         long callingId = Binder.clearCallingIdentity();
   5203         try {
   5204             IPackageManager pm = AppGlobals.getPackageManager();
   5205             synchronized(this) {
   5206                 int appId = -1;
   5207                 try {
   5208                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   5209                 } catch (RemoteException e) {
   5210                 }
   5211                 if (appId == -1) {
   5212                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5213                     return;
   5214                 }
   5215                 killPackageProcessesLocked(packageName, appId, userId,
   5216                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5217             }
   5218         } finally {
   5219             Binder.restoreCallingIdentity(callingId);
   5220         }
   5221     }
   5222 
   5223     @Override
   5224     public void killAllBackgroundProcesses() {
   5225         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5226                 != PackageManager.PERMISSION_GRANTED) {
   5227             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5228                     + Binder.getCallingPid()
   5229                     + ", uid=" + Binder.getCallingUid()
   5230                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5231             Slog.w(TAG, msg);
   5232             throw new SecurityException(msg);
   5233         }
   5234 
   5235         long callingId = Binder.clearCallingIdentity();
   5236         try {
   5237             synchronized(this) {
   5238                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5239                 final int NP = mProcessNames.getMap().size();
   5240                 for (int ip=0; ip<NP; ip++) {
   5241                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5242                     final int NA = apps.size();
   5243                     for (int ia=0; ia<NA; ia++) {
   5244                         ProcessRecord app = apps.valueAt(ia);
   5245                         if (app.persistent) {
   5246                             // we don't kill persistent processes
   5247                             continue;
   5248                         }
   5249                         if (app.removed) {
   5250                             procs.add(app);
   5251                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5252                             app.removed = true;
   5253                             procs.add(app);
   5254                         }
   5255                     }
   5256                 }
   5257 
   5258                 int N = procs.size();
   5259                 for (int i=0; i<N; i++) {
   5260                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5261                 }
   5262                 mAllowLowerMemLevel = true;
   5263                 updateOomAdjLocked();
   5264                 doLowMemReportIfNeededLocked(null);
   5265             }
   5266         } finally {
   5267             Binder.restoreCallingIdentity(callingId);
   5268         }
   5269     }
   5270 
   5271     @Override
   5272     public void forceStopPackage(final String packageName, int userId) {
   5273         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5274                 != PackageManager.PERMISSION_GRANTED) {
   5275             String msg = "Permission Denial: forceStopPackage() from pid="
   5276                     + Binder.getCallingPid()
   5277                     + ", uid=" + Binder.getCallingUid()
   5278                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5279             Slog.w(TAG, msg);
   5280             throw new SecurityException(msg);
   5281         }
   5282         final int callingPid = Binder.getCallingPid();
   5283         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
   5284                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5285         long callingId = Binder.clearCallingIdentity();
   5286         try {
   5287             IPackageManager pm = AppGlobals.getPackageManager();
   5288             synchronized(this) {
   5289                 int[] users = userId == UserHandle.USER_ALL
   5290                         ? getUsersLocked() : new int[] { userId };
   5291                 for (int user : users) {
   5292                     int pkgUid = -1;
   5293                     try {
   5294                         pkgUid = pm.getPackageUid(packageName, user);
   5295                     } catch (RemoteException e) {
   5296                     }
   5297                     if (pkgUid == -1) {
   5298                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5299                         continue;
   5300                     }
   5301                     try {
   5302                         pm.setPackageStoppedState(packageName, true, user);
   5303                     } catch (RemoteException e) {
   5304                     } catch (IllegalArgumentException e) {
   5305                         Slog.w(TAG, "Failed trying to unstop package "
   5306                                 + packageName + ": " + e);
   5307                     }
   5308                     if (isUserRunningLocked(user, false)) {
   5309                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5310                     }
   5311                 }
   5312             }
   5313         } finally {
   5314             Binder.restoreCallingIdentity(callingId);
   5315         }
   5316     }
   5317 
   5318     @Override
   5319     public void addPackageDependency(String packageName) {
   5320         synchronized (this) {
   5321             int callingPid = Binder.getCallingPid();
   5322             if (callingPid == Process.myPid()) {
   5323                 //  Yeah, um, no.
   5324                 return;
   5325             }
   5326             ProcessRecord proc;
   5327             synchronized (mPidsSelfLocked) {
   5328                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5329             }
   5330             if (proc != null) {
   5331                 if (proc.pkgDeps == null) {
   5332                     proc.pkgDeps = new ArraySet<String>(1);
   5333                 }
   5334                 proc.pkgDeps.add(packageName);
   5335             }
   5336         }
   5337     }
   5338 
   5339     /*
   5340      * The pkg name and app id have to be specified.
   5341      */
   5342     @Override
   5343     public void killApplicationWithAppId(String pkg, int appid, String reason) {
   5344         if (pkg == null) {
   5345             return;
   5346         }
   5347         // Make sure the uid is valid.
   5348         if (appid < 0) {
   5349             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5350             return;
   5351         }
   5352         int callerUid = Binder.getCallingUid();
   5353         // Only the system server can kill an application
   5354         if (callerUid == Process.SYSTEM_UID) {
   5355             // Post an aysnc message to kill the application
   5356             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5357             msg.arg1 = appid;
   5358             msg.arg2 = 0;
   5359             Bundle bundle = new Bundle();
   5360             bundle.putString("pkg", pkg);
   5361             bundle.putString("reason", reason);
   5362             msg.obj = bundle;
   5363             mHandler.sendMessage(msg);
   5364         } else {
   5365             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5366                     pkg);
   5367         }
   5368     }
   5369 
   5370     @Override
   5371     public void closeSystemDialogs(String reason) {
   5372         enforceNotIsolatedCaller("closeSystemDialogs");
   5373 
   5374         final int pid = Binder.getCallingPid();
   5375         final int uid = Binder.getCallingUid();
   5376         final long origId = Binder.clearCallingIdentity();
   5377         try {
   5378             synchronized (this) {
   5379                 // Only allow this from foreground processes, so that background
   5380                 // applications can't abuse it to prevent system UI from being shown.
   5381                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5382                     ProcessRecord proc;
   5383                     synchronized (mPidsSelfLocked) {
   5384                         proc = mPidsSelfLocked.get(pid);
   5385                     }
   5386                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5387                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5388                                 + " from background process " + proc);
   5389                         return;
   5390                     }
   5391                 }
   5392                 closeSystemDialogsLocked(reason);
   5393             }
   5394         } finally {
   5395             Binder.restoreCallingIdentity(origId);
   5396         }
   5397     }
   5398 
   5399     void closeSystemDialogsLocked(String reason) {
   5400         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5401         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5402                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5403         if (reason != null) {
   5404             intent.putExtra("reason", reason);
   5405         }
   5406         mWindowManager.closeSystemDialogs(reason);
   5407 
   5408         mStackSupervisor.closeSystemDialogsLocked();
   5409 
   5410         broadcastIntentLocked(null, null, intent, null,
   5411                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   5412                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   5413     }
   5414 
   5415     @Override
   5416     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5417         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5418         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5419         for (int i=pids.length-1; i>=0; i--) {
   5420             ProcessRecord proc;
   5421             int oomAdj;
   5422             synchronized (this) {
   5423                 synchronized (mPidsSelfLocked) {
   5424                     proc = mPidsSelfLocked.get(pids[i]);
   5425                     oomAdj = proc != null ? proc.setAdj : 0;
   5426                 }
   5427             }
   5428             infos[i] = new Debug.MemoryInfo();
   5429             Debug.getMemoryInfo(pids[i], infos[i]);
   5430             if (proc != null) {
   5431                 synchronized (this) {
   5432                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5433                         // Record this for posterity if the process has been stable.
   5434                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5435                                 infos[i].getTotalUss(), false, proc.pkgList);
   5436                     }
   5437                 }
   5438             }
   5439         }
   5440         return infos;
   5441     }
   5442 
   5443     @Override
   5444     public long[] getProcessPss(int[] pids) {
   5445         enforceNotIsolatedCaller("getProcessPss");
   5446         long[] pss = new long[pids.length];
   5447         for (int i=pids.length-1; i>=0; i--) {
   5448             ProcessRecord proc;
   5449             int oomAdj;
   5450             synchronized (this) {
   5451                 synchronized (mPidsSelfLocked) {
   5452                     proc = mPidsSelfLocked.get(pids[i]);
   5453                     oomAdj = proc != null ? proc.setAdj : 0;
   5454                 }
   5455             }
   5456             long[] tmpUss = new long[1];
   5457             pss[i] = Debug.getPss(pids[i], tmpUss, null);
   5458             if (proc != null) {
   5459                 synchronized (this) {
   5460                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5461                         // Record this for posterity if the process has been stable.
   5462                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5463                     }
   5464                 }
   5465             }
   5466         }
   5467         return pss;
   5468     }
   5469 
   5470     @Override
   5471     public void killApplicationProcess(String processName, int uid) {
   5472         if (processName == null) {
   5473             return;
   5474         }
   5475 
   5476         int callerUid = Binder.getCallingUid();
   5477         // Only the system server can kill an application
   5478         if (callerUid == Process.SYSTEM_UID) {
   5479             synchronized (this) {
   5480                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5481                 if (app != null && app.thread != null) {
   5482                     try {
   5483                         app.thread.scheduleSuicide();
   5484                     } catch (RemoteException e) {
   5485                         // If the other end already died, then our work here is done.
   5486                     }
   5487                 } else {
   5488                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5489                             + processName + " / " + uid);
   5490                 }
   5491             }
   5492         } else {
   5493             throw new SecurityException(callerUid + " cannot kill app process: " +
   5494                     processName);
   5495         }
   5496     }
   5497 
   5498     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5499         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5500                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5501         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5502                 Uri.fromParts("package", packageName, null));
   5503         if (!mProcessesReady) {
   5504             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5505                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5506         }
   5507         intent.putExtra(Intent.EXTRA_UID, uid);
   5508         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5509         broadcastIntentLocked(null, null, intent,
   5510                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5511                 false, false,
   5512                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5513     }
   5514 
   5515     private void forceStopUserLocked(int userId, String reason) {
   5516         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
   5517         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   5518         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5519                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5520         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   5521         broadcastIntentLocked(null, null, intent,
   5522                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5523                 false, false,
   5524                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5525     }
   5526 
   5527     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5528             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5529             boolean doit, boolean evenPersistent, String reason) {
   5530         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5531 
   5532         // Remove all processes this package may have touched: all with the
   5533         // same UID (except for the system or root user), and all whose name
   5534         // matches the package name.
   5535         final int NP = mProcessNames.getMap().size();
   5536         for (int ip=0; ip<NP; ip++) {
   5537             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5538             final int NA = apps.size();
   5539             for (int ia=0; ia<NA; ia++) {
   5540                 ProcessRecord app = apps.valueAt(ia);
   5541                 if (app.persistent && !evenPersistent) {
   5542                     // we don't kill persistent processes
   5543                     continue;
   5544                 }
   5545                 if (app.removed) {
   5546                     if (doit) {
   5547                         procs.add(app);
   5548                     }
   5549                     continue;
   5550                 }
   5551 
   5552                 // Skip process if it doesn't meet our oom adj requirement.
   5553                 if (app.setAdj < minOomAdj) {
   5554                     continue;
   5555                 }
   5556 
   5557                 // If no package is specified, we call all processes under the
   5558                 // give user id.
   5559                 if (packageName == null) {
   5560                     if (app.userId != userId) {
   5561                         continue;
   5562                     }
   5563                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5564                         continue;
   5565                     }
   5566                 // Package has been specified, we want to hit all processes
   5567                 // that match it.  We need to qualify this by the processes
   5568                 // that are running under the specified app and user ID.
   5569                 } else {
   5570                     final boolean isDep = app.pkgDeps != null
   5571                             && app.pkgDeps.contains(packageName);
   5572                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   5573                         continue;
   5574                     }
   5575                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5576                         continue;
   5577                     }
   5578                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   5579                         continue;
   5580                     }
   5581                 }
   5582 
   5583                 // Process has passed all conditions, kill it!
   5584                 if (!doit) {
   5585                     return true;
   5586                 }
   5587                 app.removed = true;
   5588                 procs.add(app);
   5589             }
   5590         }
   5591 
   5592         int N = procs.size();
   5593         for (int i=0; i<N; i++) {
   5594             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   5595         }
   5596         updateOomAdjLocked();
   5597         return N > 0;
   5598     }
   5599 
   5600     private final boolean forceStopPackageLocked(String name, int appId,
   5601             boolean callerWillRestart, boolean purgeCache, boolean doit,
   5602             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   5603         int i;
   5604         int N;
   5605 
   5606         if (userId == UserHandle.USER_ALL && name == null) {
   5607             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   5608         }
   5609 
   5610         if (appId < 0 && name != null) {
   5611             try {
   5612                 appId = UserHandle.getAppId(
   5613                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   5614             } catch (RemoteException e) {
   5615             }
   5616         }
   5617 
   5618         if (doit) {
   5619             if (name != null) {
   5620                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
   5621                         + " user=" + userId + ": " + reason);
   5622             } else {
   5623                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   5624             }
   5625 
   5626             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   5627             for (int ip=pmap.size()-1; ip>=0; ip--) {
   5628                 SparseArray<Long> ba = pmap.valueAt(ip);
   5629                 for (i=ba.size()-1; i>=0; i--) {
   5630                     boolean remove = false;
   5631                     final int entUid = ba.keyAt(i);
   5632                     if (name != null) {
   5633                         if (userId == UserHandle.USER_ALL) {
   5634                             if (UserHandle.getAppId(entUid) == appId) {
   5635                                 remove = true;
   5636                             }
   5637                         } else {
   5638                             if (entUid == UserHandle.getUid(userId, appId)) {
   5639                                 remove = true;
   5640                             }
   5641                         }
   5642                     } else if (UserHandle.getUserId(entUid) == userId) {
   5643                         remove = true;
   5644                     }
   5645                     if (remove) {
   5646                         ba.removeAt(i);
   5647                     }
   5648                 }
   5649                 if (ba.size() == 0) {
   5650                     pmap.removeAt(ip);
   5651                 }
   5652             }
   5653         }
   5654 
   5655         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   5656                 -100, callerWillRestart, true, doit, evenPersistent,
   5657                 name == null ? ("stop user " + userId) : ("stop " + name));
   5658 
   5659         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   5660             if (!doit) {
   5661                 return true;
   5662             }
   5663             didSomething = true;
   5664         }
   5665 
   5666         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   5667             if (!doit) {
   5668                 return true;
   5669             }
   5670             didSomething = true;
   5671         }
   5672 
   5673         if (name == null) {
   5674             // Remove all sticky broadcasts from this user.
   5675             mStickyBroadcasts.remove(userId);
   5676         }
   5677 
   5678         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   5679         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   5680                 userId, providers)) {
   5681             if (!doit) {
   5682                 return true;
   5683             }
   5684             didSomething = true;
   5685         }
   5686         N = providers.size();
   5687         for (i=0; i<N; i++) {
   5688             removeDyingProviderLocked(null, providers.get(i), true);
   5689         }
   5690 
   5691         // Remove transient permissions granted from/to this package/user
   5692         removeUriPermissionsForPackageLocked(name, userId, false);
   5693 
   5694         if (name == null || uninstalling) {
   5695             // Remove pending intents.  For now we only do this when force
   5696             // stopping users, because we have some problems when doing this
   5697             // for packages -- app widgets are not currently cleaned up for
   5698             // such packages, so they can be left with bad pending intents.
   5699             if (mIntentSenderRecords.size() > 0) {
   5700                 Iterator<WeakReference<PendingIntentRecord>> it
   5701                         = mIntentSenderRecords.values().iterator();
   5702                 while (it.hasNext()) {
   5703                     WeakReference<PendingIntentRecord> wpir = it.next();
   5704                     if (wpir == null) {
   5705                         it.remove();
   5706                         continue;
   5707                     }
   5708                     PendingIntentRecord pir = wpir.get();
   5709                     if (pir == null) {
   5710                         it.remove();
   5711                         continue;
   5712                     }
   5713                     if (name == null) {
   5714                         // Stopping user, remove all objects for the user.
   5715                         if (pir.key.userId != userId) {
   5716                             // Not the same user, skip it.
   5717                             continue;
   5718                         }
   5719                     } else {
   5720                         if (UserHandle.getAppId(pir.uid) != appId) {
   5721                             // Different app id, skip it.
   5722                             continue;
   5723                         }
   5724                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   5725                             // Different user, skip it.
   5726                             continue;
   5727                         }
   5728                         if (!pir.key.packageName.equals(name)) {
   5729                             // Different package, skip it.
   5730                             continue;
   5731                         }
   5732                     }
   5733                     if (!doit) {
   5734                         return true;
   5735                     }
   5736                     didSomething = true;
   5737                     it.remove();
   5738                     pir.canceled = true;
   5739                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
   5740                         pir.key.activity.pendingResults.remove(pir.ref);
   5741                     }
   5742                 }
   5743             }
   5744         }
   5745 
   5746         if (doit) {
   5747             if (purgeCache && name != null) {
   5748                 AttributeCache ac = AttributeCache.instance();
   5749                 if (ac != null) {
   5750                     ac.removePackage(name);
   5751                 }
   5752             }
   5753             if (mBooted) {
   5754                 mStackSupervisor.resumeTopActivitiesLocked();
   5755                 mStackSupervisor.scheduleIdleLocked();
   5756             }
   5757         }
   5758 
   5759         return didSomething;
   5760     }
   5761 
   5762     private final boolean removeProcessLocked(ProcessRecord app,
   5763             boolean callerWillRestart, boolean allowRestart, String reason) {
   5764         final String name = app.processName;
   5765         final int uid = app.uid;
   5766         if (DEBUG_PROCESSES) Slog.d(
   5767             TAG, "Force removing proc " + app.toShortString() + " (" + name
   5768             + "/" + uid + ")");
   5769 
   5770         mProcessNames.remove(name, uid);
   5771         mIsolatedProcesses.remove(app.uid);
   5772         if (mHeavyWeightProcess == app) {
   5773             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5774                     mHeavyWeightProcess.userId, 0));
   5775             mHeavyWeightProcess = null;
   5776         }
   5777         boolean needRestart = false;
   5778         if (app.pid > 0 && app.pid != MY_PID) {
   5779             int pid = app.pid;
   5780             synchronized (mPidsSelfLocked) {
   5781                 mPidsSelfLocked.remove(pid);
   5782                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5783             }
   5784             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   5785             if (app.isolated) {
   5786                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   5787             }
   5788             app.kill(reason, true);
   5789             handleAppDiedLocked(app, true, allowRestart);
   5790             removeLruProcessLocked(app);
   5791 
   5792             if (app.persistent && !app.isolated) {
   5793                 if (!callerWillRestart) {
   5794                     addAppLocked(app.info, false, null /* ABI override */);
   5795                 } else {
   5796                     needRestart = true;
   5797                 }
   5798             }
   5799         } else {
   5800             mRemovedProcesses.add(app);
   5801         }
   5802 
   5803         return needRestart;
   5804     }
   5805 
   5806     private final void processStartTimedOutLocked(ProcessRecord app) {
   5807         final int pid = app.pid;
   5808         boolean gone = false;
   5809         synchronized (mPidsSelfLocked) {
   5810             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   5811             if (knownApp != null && knownApp.thread == null) {
   5812                 mPidsSelfLocked.remove(pid);
   5813                 gone = true;
   5814             }
   5815         }
   5816 
   5817         if (gone) {
   5818             Slog.w(TAG, "Process " + app + " failed to attach");
   5819             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   5820                     pid, app.uid, app.processName);
   5821             mProcessNames.remove(app.processName, app.uid);
   5822             mIsolatedProcesses.remove(app.uid);
   5823             if (mHeavyWeightProcess == app) {
   5824                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5825                         mHeavyWeightProcess.userId, 0));
   5826                 mHeavyWeightProcess = null;
   5827             }
   5828             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   5829             if (app.isolated) {
   5830                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   5831             }
   5832             // Take care of any launching providers waiting for this process.
   5833             checkAppInLaunchingProvidersLocked(app, true);
   5834             // Take care of any services that are waiting for the process.
   5835             mServices.processStartTimedOutLocked(app);
   5836             app.kill("start timeout", true);
   5837             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   5838                 Slog.w(TAG, "Unattached app died before backup, skipping");
   5839                 try {
   5840                     IBackupManager bm = IBackupManager.Stub.asInterface(
   5841                             ServiceManager.getService(Context.BACKUP_SERVICE));
   5842                     bm.agentDisconnected(app.info.packageName);
   5843                 } catch (RemoteException e) {
   5844                     // Can't happen; the backup manager is local
   5845                 }
   5846             }
   5847             if (isPendingBroadcastProcessLocked(pid)) {
   5848                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   5849                 skipPendingBroadcastLocked(pid);
   5850             }
   5851         } else {
   5852             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   5853         }
   5854     }
   5855 
   5856     private final boolean attachApplicationLocked(IApplicationThread thread,
   5857             int pid) {
   5858 
   5859         // Find the application record that is being attached...  either via
   5860         // the pid if we are running in multiple processes, or just pull the
   5861         // next app record if we are emulating process with anonymous threads.
   5862         ProcessRecord app;
   5863         if (pid != MY_PID && pid >= 0) {
   5864             synchronized (mPidsSelfLocked) {
   5865                 app = mPidsSelfLocked.get(pid);
   5866             }
   5867         } else {
   5868             app = null;
   5869         }
   5870 
   5871         if (app == null) {
   5872             Slog.w(TAG, "No pending application record for pid " + pid
   5873                     + " (IApplicationThread " + thread + "); dropping process");
   5874             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   5875             if (pid > 0 && pid != MY_PID) {
   5876                 Process.killProcessQuiet(pid);
   5877                 //TODO: Process.killProcessGroup(app.info.uid, pid);
   5878             } else {
   5879                 try {
   5880                     thread.scheduleExit();
   5881                 } catch (Exception e) {
   5882                     // Ignore exceptions.
   5883                 }
   5884             }
   5885             return false;
   5886         }
   5887 
   5888         // If this application record is still attached to a previous
   5889         // process, clean it up now.
   5890         if (app.thread != null) {
   5891             handleAppDiedLocked(app, true, true);
   5892         }
   5893 
   5894         // Tell the process all about itself.
   5895 
   5896         if (localLOGV) Slog.v(
   5897                 TAG, "Binding process pid " + pid + " to record " + app);
   5898 
   5899         final String processName = app.processName;
   5900         try {
   5901             AppDeathRecipient adr = new AppDeathRecipient(
   5902                     app, pid, thread);
   5903             thread.asBinder().linkToDeath(adr, 0);
   5904             app.deathRecipient = adr;
   5905         } catch (RemoteException e) {
   5906             app.resetPackageList(mProcessStats);
   5907             startProcessLocked(app, "link fail", processName);
   5908             return false;
   5909         }
   5910 
   5911         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   5912 
   5913         app.makeActive(thread, mProcessStats);
   5914         app.curAdj = app.setAdj = -100;
   5915         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
   5916         app.forcingToForeground = null;
   5917         updateProcessForegroundLocked(app, false, false);
   5918         app.hasShownUi = false;
   5919         app.debugging = false;
   5920         app.cached = false;
   5921         app.killedByAm = false;
   5922 
   5923         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5924 
   5925         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   5926         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   5927 
   5928         if (!normalMode) {
   5929             Slog.i(TAG, "Launching preboot mode app: " + app);
   5930         }
   5931 
   5932         if (localLOGV) Slog.v(
   5933             TAG, "New app record " + app
   5934             + " thread=" + thread.asBinder() + " pid=" + pid);
   5935         try {
   5936             int testMode = IApplicationThread.DEBUG_OFF;
   5937             if (mDebugApp != null && mDebugApp.equals(processName)) {
   5938                 testMode = mWaitForDebugger
   5939                     ? IApplicationThread.DEBUG_WAIT
   5940                     : IApplicationThread.DEBUG_ON;
   5941                 app.debugging = true;
   5942                 if (mDebugTransient) {
   5943                     mDebugApp = mOrigDebugApp;
   5944                     mWaitForDebugger = mOrigWaitForDebugger;
   5945                 }
   5946             }
   5947             String profileFile = app.instrumentationProfileFile;
   5948             ParcelFileDescriptor profileFd = null;
   5949             int samplingInterval = 0;
   5950             boolean profileAutoStop = false;
   5951             if (mProfileApp != null && mProfileApp.equals(processName)) {
   5952                 mProfileProc = app;
   5953                 profileFile = mProfileFile;
   5954                 profileFd = mProfileFd;
   5955                 samplingInterval = mSamplingInterval;
   5956                 profileAutoStop = mAutoStopProfiler;
   5957             }
   5958             boolean enableOpenGlTrace = false;
   5959             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   5960                 enableOpenGlTrace = true;
   5961                 mOpenGlTraceApp = null;
   5962             }
   5963 
   5964             // If the app is being launched for restore or full backup, set it up specially
   5965             boolean isRestrictedBackupMode = false;
   5966             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   5967                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   5968                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   5969                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   5970             }
   5971 
   5972             ensurePackageDexOpt(app.instrumentationInfo != null
   5973                     ? app.instrumentationInfo.packageName
   5974                     : app.info.packageName);
   5975             if (app.instrumentationClass != null) {
   5976                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   5977             }
   5978             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   5979                     + processName + " with config " + mConfiguration);
   5980             ApplicationInfo appInfo = app.instrumentationInfo != null
   5981                     ? app.instrumentationInfo : app.info;
   5982             app.compat = compatibilityInfoForPackageLocked(appInfo);
   5983             if (profileFd != null) {
   5984                 profileFd = profileFd.dup();
   5985             }
   5986             ProfilerInfo profilerInfo = profileFile == null ? null
   5987                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   5988             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   5989                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   5990                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   5991                     isRestrictedBackupMode || !normalMode, app.persistent,
   5992                     new Configuration(mConfiguration), app.compat,
   5993                     getCommonServicesLocked(app.isolated),
   5994                     mCoreSettingsObserver.getCoreSettingsLocked());
   5995             updateLruProcessLocked(app, false, null);
   5996             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   5997         } catch (Exception e) {
   5998             // todo: Yikes!  What should we do?  For now we will try to
   5999             // start another process, but that could easily get us in
   6000             // an infinite loop of restarting processes...
   6001             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6002 
   6003             app.resetPackageList(mProcessStats);
   6004             app.unlinkDeathRecipient();
   6005             startProcessLocked(app, "bind fail", processName);
   6006             return false;
   6007         }
   6008 
   6009         // Remove this record from the list of starting applications.
   6010         mPersistentStartingProcesses.remove(app);
   6011         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   6012                 "Attach application locked removing on hold: " + app);
   6013         mProcessesOnHold.remove(app);
   6014 
   6015         boolean badApp = false;
   6016         boolean didSomething = false;
   6017 
   6018         // See if the top visible activity is waiting to run in this process...
   6019         if (normalMode) {
   6020             try {
   6021                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6022                     didSomething = true;
   6023                 }
   6024             } catch (Exception e) {
   6025                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6026                 badApp = true;
   6027             }
   6028         }
   6029 
   6030         // Find any services that should be running in this process...
   6031         if (!badApp) {
   6032             try {
   6033                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6034             } catch (Exception e) {
   6035                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6036                 badApp = true;
   6037             }
   6038         }
   6039 
   6040         // Check if a next-broadcast receiver is in this process...
   6041         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6042             try {
   6043                 didSomething |= sendPendingBroadcastsLocked(app);
   6044             } catch (Exception e) {
   6045                 // If the app died trying to launch the receiver we declare it 'bad'
   6046                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6047                 badApp = true;
   6048             }
   6049         }
   6050 
   6051         // Check whether the next backup agent is in this process...
   6052         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6053             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   6054             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   6055             try {
   6056                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6057                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6058                         mBackupTarget.backupMode);
   6059             } catch (Exception e) {
   6060                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6061                 badApp = true;
   6062             }
   6063         }
   6064 
   6065         if (badApp) {
   6066             app.kill("error during init", true);
   6067             handleAppDiedLocked(app, false, true);
   6068             return false;
   6069         }
   6070 
   6071         if (!didSomething) {
   6072             updateOomAdjLocked();
   6073         }
   6074 
   6075         return true;
   6076     }
   6077 
   6078     @Override
   6079     public final void attachApplication(IApplicationThread thread) {
   6080         synchronized (this) {
   6081             int callingPid = Binder.getCallingPid();
   6082             final long origId = Binder.clearCallingIdentity();
   6083             attachApplicationLocked(thread, callingPid);
   6084             Binder.restoreCallingIdentity(origId);
   6085         }
   6086     }
   6087 
   6088     @Override
   6089     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6090         final long origId = Binder.clearCallingIdentity();
   6091         synchronized (this) {
   6092             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6093             if (stack != null) {
   6094                 ActivityRecord r =
   6095                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6096                 if (stopProfiling) {
   6097                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6098                         try {
   6099                             mProfileFd.close();
   6100                         } catch (IOException e) {
   6101                         }
   6102                         clearProfilerLocked();
   6103                     }
   6104                 }
   6105             }
   6106         }
   6107         Binder.restoreCallingIdentity(origId);
   6108     }
   6109 
   6110     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6111         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6112                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
   6113     }
   6114 
   6115     void enableScreenAfterBoot() {
   6116         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6117                 SystemClock.uptimeMillis());
   6118         mWindowManager.enableScreenAfterBoot();
   6119 
   6120         synchronized (this) {
   6121             updateEventDispatchingLocked();
   6122         }
   6123     }
   6124 
   6125     @Override
   6126     public void showBootMessage(final CharSequence msg, final boolean always) {
   6127         enforceNotIsolatedCaller("showBootMessage");
   6128         mWindowManager.showBootMessage(msg, always);
   6129     }
   6130 
   6131     @Override
   6132     public void keyguardWaitingForActivityDrawn() {
   6133         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6134         final long token = Binder.clearCallingIdentity();
   6135         try {
   6136             synchronized (this) {
   6137                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6138                 mWindowManager.keyguardWaitingForActivityDrawn();
   6139                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
   6140                     mLockScreenShown = LOCK_SCREEN_LEAVING;
   6141                     updateSleepIfNeededLocked();
   6142                 }
   6143             }
   6144         } finally {
   6145             Binder.restoreCallingIdentity(token);
   6146         }
   6147     }
   6148 
   6149     final void finishBooting() {
   6150         synchronized (this) {
   6151             if (!mBootAnimationComplete) {
   6152                 mCallFinishBooting = true;
   6153                 return;
   6154             }
   6155             mCallFinishBooting = false;
   6156         }
   6157 
   6158         ArraySet<String> completedIsas = new ArraySet<String>();
   6159         for (String abi : Build.SUPPORTED_ABIS) {
   6160             Process.establishZygoteConnectionForAbi(abi);
   6161             final String instructionSet = VMRuntime.getInstructionSet(abi);
   6162             if (!completedIsas.contains(instructionSet)) {
   6163                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
   6164                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
   6165                 }
   6166                 completedIsas.add(instructionSet);
   6167             }
   6168         }
   6169 
   6170         IntentFilter pkgFilter = new IntentFilter();
   6171         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   6172         pkgFilter.addDataScheme("package");
   6173         mContext.registerReceiver(new BroadcastReceiver() {
   6174             @Override
   6175             public void onReceive(Context context, Intent intent) {
   6176                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   6177                 if (pkgs != null) {
   6178                     for (String pkg : pkgs) {
   6179                         synchronized (ActivityManagerService.this) {
   6180                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   6181                                     0, "finished booting")) {
   6182                                 setResultCode(Activity.RESULT_OK);
   6183                                 return;
   6184                             }
   6185                         }
   6186                     }
   6187                 }
   6188             }
   6189         }, pkgFilter);
   6190 
   6191         // Let system services know.
   6192         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6193 
   6194         synchronized (this) {
   6195             // Ensure that any processes we had put on hold are now started
   6196             // up.
   6197             final int NP = mProcessesOnHold.size();
   6198             if (NP > 0) {
   6199                 ArrayList<ProcessRecord> procs =
   6200                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6201                 for (int ip=0; ip<NP; ip++) {
   6202                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   6203                             + procs.get(ip));
   6204                     startProcessLocked(procs.get(ip), "on-hold", null);
   6205                 }
   6206             }
   6207 
   6208             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6209                 // Start looking for apps that are abusing wake locks.
   6210                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6211                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6212                 // Tell anyone interested that we are done booting!
   6213                 SystemProperties.set("sys.boot_completed", "1");
   6214 
   6215                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6216                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6217                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6218                     SystemProperties.set("dev.bootcomplete", "1");
   6219                 }
   6220                 for (int i=0; i<mStartedUsers.size(); i++) {
   6221                     UserStartedState uss = mStartedUsers.valueAt(i);
   6222                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   6223                         uss.mState = UserStartedState.STATE_RUNNING;
   6224                         final int userId = mStartedUsers.keyAt(i);
   6225                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   6226                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   6227                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   6228                         broadcastIntentLocked(null, null, intent, null,
   6229                                 new IIntentReceiver.Stub() {
   6230                                     @Override
   6231                                     public void performReceive(Intent intent, int resultCode,
   6232                                             String data, Bundle extras, boolean ordered,
   6233                                             boolean sticky, int sendingUser) {
   6234                                         synchronized (ActivityManagerService.this) {
   6235                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6236                                                     true, false);
   6237                                         }
   6238                                     }
   6239                                 },
   6240                                 0, null, null,
   6241                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   6242                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
   6243                                 userId);
   6244                     }
   6245                 }
   6246                 scheduleStartProfilesLocked();
   6247             }
   6248         }
   6249     }
   6250 
   6251     @Override
   6252     public void bootAnimationComplete() {
   6253         final boolean callFinishBooting;
   6254         synchronized (this) {
   6255             callFinishBooting = mCallFinishBooting;
   6256             mBootAnimationComplete = true;
   6257         }
   6258         if (callFinishBooting) {
   6259             finishBooting();
   6260         }
   6261     }
   6262 
   6263     @Override
   6264     public void systemBackupRestored() {
   6265         synchronized (this) {
   6266             if (mSystemReady) {
   6267                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
   6268             } else {
   6269                 Slog.w(TAG, "System backup restored before system is ready");
   6270             }
   6271         }
   6272     }
   6273 
   6274     final void ensureBootCompleted() {
   6275         boolean booting;
   6276         boolean enableScreen;
   6277         synchronized (this) {
   6278             booting = mBooting;
   6279             mBooting = false;
   6280             enableScreen = !mBooted;
   6281             mBooted = true;
   6282         }
   6283 
   6284         if (booting) {
   6285             finishBooting();
   6286         }
   6287 
   6288         if (enableScreen) {
   6289             enableScreenAfterBoot();
   6290         }
   6291     }
   6292 
   6293     @Override
   6294     public final void activityResumed(IBinder token) {
   6295         final long origId = Binder.clearCallingIdentity();
   6296         synchronized(this) {
   6297             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6298             if (stack != null) {
   6299                 ActivityRecord.activityResumedLocked(token);
   6300             }
   6301         }
   6302         Binder.restoreCallingIdentity(origId);
   6303     }
   6304 
   6305     @Override
   6306     public final void activityPaused(IBinder token) {
   6307         final long origId = Binder.clearCallingIdentity();
   6308         synchronized(this) {
   6309             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6310             if (stack != null) {
   6311                 stack.activityPausedLocked(token, false);
   6312             }
   6313         }
   6314         Binder.restoreCallingIdentity(origId);
   6315     }
   6316 
   6317     @Override
   6318     public final void activityStopped(IBinder token, Bundle icicle,
   6319             PersistableBundle persistentState, CharSequence description) {
   6320         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
   6321 
   6322         // Refuse possible leaked file descriptors
   6323         if (icicle != null && icicle.hasFileDescriptors()) {
   6324             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6325         }
   6326 
   6327         final long origId = Binder.clearCallingIdentity();
   6328 
   6329         synchronized (this) {
   6330             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6331             if (r != null) {
   6332                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6333             }
   6334         }
   6335 
   6336         trimApplications();
   6337 
   6338         Binder.restoreCallingIdentity(origId);
   6339     }
   6340 
   6341     @Override
   6342     public final void activityDestroyed(IBinder token) {
   6343         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   6344         synchronized (this) {
   6345             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6346             if (stack != null) {
   6347                 stack.activityDestroyedLocked(token, "activityDestroyed");
   6348             }
   6349         }
   6350     }
   6351 
   6352     @Override
   6353     public final void backgroundResourcesReleased(IBinder token) {
   6354         final long origId = Binder.clearCallingIdentity();
   6355         try {
   6356             synchronized (this) {
   6357                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6358                 if (stack != null) {
   6359                     stack.backgroundResourcesReleased();
   6360                 }
   6361             }
   6362         } finally {
   6363             Binder.restoreCallingIdentity(origId);
   6364         }
   6365     }
   6366 
   6367     @Override
   6368     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   6369         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   6370     }
   6371 
   6372     @Override
   6373     public final void notifyEnterAnimationComplete(IBinder token) {
   6374         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   6375     }
   6376 
   6377     @Override
   6378     public String getCallingPackage(IBinder token) {
   6379         synchronized (this) {
   6380             ActivityRecord r = getCallingRecordLocked(token);
   6381             return r != null ? r.info.packageName : null;
   6382         }
   6383     }
   6384 
   6385     @Override
   6386     public ComponentName getCallingActivity(IBinder token) {
   6387         synchronized (this) {
   6388             ActivityRecord r = getCallingRecordLocked(token);
   6389             return r != null ? r.intent.getComponent() : null;
   6390         }
   6391     }
   6392 
   6393     private ActivityRecord getCallingRecordLocked(IBinder token) {
   6394         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6395         if (r == null) {
   6396             return null;
   6397         }
   6398         return r.resultTo;
   6399     }
   6400 
   6401     @Override
   6402     public ComponentName getActivityClassForToken(IBinder token) {
   6403         synchronized(this) {
   6404             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6405             if (r == null) {
   6406                 return null;
   6407             }
   6408             return r.intent.getComponent();
   6409         }
   6410     }
   6411 
   6412     @Override
   6413     public String getPackageForToken(IBinder token) {
   6414         synchronized(this) {
   6415             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6416             if (r == null) {
   6417                 return null;
   6418             }
   6419             return r.packageName;
   6420         }
   6421     }
   6422 
   6423     @Override
   6424     public IIntentSender getIntentSender(int type,
   6425             String packageName, IBinder token, String resultWho,
   6426             int requestCode, Intent[] intents, String[] resolvedTypes,
   6427             int flags, Bundle options, int userId) {
   6428         enforceNotIsolatedCaller("getIntentSender");
   6429         // Refuse possible leaked file descriptors
   6430         if (intents != null) {
   6431             if (intents.length < 1) {
   6432                 throw new IllegalArgumentException("Intents array length must be >= 1");
   6433             }
   6434             for (int i=0; i<intents.length; i++) {
   6435                 Intent intent = intents[i];
   6436                 if (intent != null) {
   6437                     if (intent.hasFileDescriptors()) {
   6438                         throw new IllegalArgumentException("File descriptors passed in Intent");
   6439                     }
   6440                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   6441                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   6442                         throw new IllegalArgumentException(
   6443                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   6444                     }
   6445                     intents[i] = new Intent(intent);
   6446                 }
   6447             }
   6448             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   6449                 throw new IllegalArgumentException(
   6450                         "Intent array length does not match resolvedTypes length");
   6451             }
   6452         }
   6453         if (options != null) {
   6454             if (options.hasFileDescriptors()) {
   6455                 throw new IllegalArgumentException("File descriptors passed in options");
   6456             }
   6457         }
   6458 
   6459         synchronized(this) {
   6460             int callingUid = Binder.getCallingUid();
   6461             int origUserId = userId;
   6462             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   6463                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   6464                     ALLOW_NON_FULL, "getIntentSender", null);
   6465             if (origUserId == UserHandle.USER_CURRENT) {
   6466                 // We don't want to evaluate this until the pending intent is
   6467                 // actually executed.  However, we do want to always do the
   6468                 // security checking for it above.
   6469                 userId = UserHandle.USER_CURRENT;
   6470             }
   6471             try {
   6472                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   6473                     int uid = AppGlobals.getPackageManager()
   6474                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   6475                     if (!UserHandle.isSameApp(callingUid, uid)) {
   6476                         String msg = "Permission Denial: getIntentSender() from pid="
   6477                             + Binder.getCallingPid()
   6478                             + ", uid=" + Binder.getCallingUid()
   6479                             + ", (need uid=" + uid + ")"
   6480                             + " is not allowed to send as package " + packageName;
   6481                         Slog.w(TAG, msg);
   6482                         throw new SecurityException(msg);
   6483                     }
   6484                 }
   6485 
   6486                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   6487                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   6488 
   6489             } catch (RemoteException e) {
   6490                 throw new SecurityException(e);
   6491             }
   6492         }
   6493     }
   6494 
   6495     IIntentSender getIntentSenderLocked(int type, String packageName,
   6496             int callingUid, int userId, IBinder token, String resultWho,
   6497             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   6498             Bundle options) {
   6499         if (DEBUG_MU)
   6500             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   6501         ActivityRecord activity = null;
   6502         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6503             activity = ActivityRecord.isInStackLocked(token);
   6504             if (activity == null) {
   6505                 return null;
   6506             }
   6507             if (activity.finishing) {
   6508                 return null;
   6509             }
   6510         }
   6511 
   6512         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   6513         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   6514         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   6515         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   6516                 |PendingIntent.FLAG_UPDATE_CURRENT);
   6517 
   6518         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   6519                 type, packageName, activity, resultWho,
   6520                 requestCode, intents, resolvedTypes, flags, options, userId);
   6521         WeakReference<PendingIntentRecord> ref;
   6522         ref = mIntentSenderRecords.get(key);
   6523         PendingIntentRecord rec = ref != null ? ref.get() : null;
   6524         if (rec != null) {
   6525             if (!cancelCurrent) {
   6526                 if (updateCurrent) {
   6527                     if (rec.key.requestIntent != null) {
   6528                         rec.key.requestIntent.replaceExtras(intents != null ?
   6529                                 intents[intents.length - 1] : null);
   6530                     }
   6531                     if (intents != null) {
   6532                         intents[intents.length-1] = rec.key.requestIntent;
   6533                         rec.key.allIntents = intents;
   6534                         rec.key.allResolvedTypes = resolvedTypes;
   6535                     } else {
   6536                         rec.key.allIntents = null;
   6537                         rec.key.allResolvedTypes = null;
   6538                     }
   6539                 }
   6540                 return rec;
   6541             }
   6542             rec.canceled = true;
   6543             mIntentSenderRecords.remove(key);
   6544         }
   6545         if (noCreate) {
   6546             return rec;
   6547         }
   6548         rec = new PendingIntentRecord(this, key, callingUid);
   6549         mIntentSenderRecords.put(key, rec.ref);
   6550         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6551             if (activity.pendingResults == null) {
   6552                 activity.pendingResults
   6553                         = new HashSet<WeakReference<PendingIntentRecord>>();
   6554             }
   6555             activity.pendingResults.add(rec.ref);
   6556         }
   6557         return rec;
   6558     }
   6559 
   6560     @Override
   6561     public void cancelIntentSender(IIntentSender sender) {
   6562         if (!(sender instanceof PendingIntentRecord)) {
   6563             return;
   6564         }
   6565         synchronized(this) {
   6566             PendingIntentRecord rec = (PendingIntentRecord)sender;
   6567             try {
   6568                 int uid = AppGlobals.getPackageManager()
   6569                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   6570                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   6571                     String msg = "Permission Denial: cancelIntentSender() from pid="
   6572                         + Binder.getCallingPid()
   6573                         + ", uid=" + Binder.getCallingUid()
   6574                         + " is not allowed to cancel packges "
   6575                         + rec.key.packageName;
   6576                     Slog.w(TAG, msg);
   6577                     throw new SecurityException(msg);
   6578                 }
   6579             } catch (RemoteException e) {
   6580                 throw new SecurityException(e);
   6581             }
   6582             cancelIntentSenderLocked(rec, true);
   6583         }
   6584     }
   6585 
   6586     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   6587         rec.canceled = true;
   6588         mIntentSenderRecords.remove(rec.key);
   6589         if (cleanActivity && rec.key.activity != null) {
   6590             rec.key.activity.pendingResults.remove(rec.ref);
   6591         }
   6592     }
   6593 
   6594     @Override
   6595     public String getPackageForIntentSender(IIntentSender pendingResult) {
   6596         if (!(pendingResult instanceof PendingIntentRecord)) {
   6597             return null;
   6598         }
   6599         try {
   6600             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6601             return res.key.packageName;
   6602         } catch (ClassCastException e) {
   6603         }
   6604         return null;
   6605     }
   6606 
   6607     @Override
   6608     public int getUidForIntentSender(IIntentSender sender) {
   6609         if (sender instanceof PendingIntentRecord) {
   6610             try {
   6611                 PendingIntentRecord res = (PendingIntentRecord)sender;
   6612                 return res.uid;
   6613             } catch (ClassCastException e) {
   6614             }
   6615         }
   6616         return -1;
   6617     }
   6618 
   6619     @Override
   6620     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   6621         if (!(pendingResult instanceof PendingIntentRecord)) {
   6622             return false;
   6623         }
   6624         try {
   6625             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6626             if (res.key.allIntents == null) {
   6627                 return false;
   6628             }
   6629             for (int i=0; i<res.key.allIntents.length; i++) {
   6630                 Intent intent = res.key.allIntents[i];
   6631                 if (intent.getPackage() != null && intent.getComponent() != null) {
   6632                     return false;
   6633                 }
   6634             }
   6635             return true;
   6636         } catch (ClassCastException e) {
   6637         }
   6638         return false;
   6639     }
   6640 
   6641     @Override
   6642     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   6643         if (!(pendingResult instanceof PendingIntentRecord)) {
   6644             return false;
   6645         }
   6646         try {
   6647             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6648             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   6649                 return true;
   6650             }
   6651             return false;
   6652         } catch (ClassCastException e) {
   6653         }
   6654         return false;
   6655     }
   6656 
   6657     @Override
   6658     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   6659         if (!(pendingResult instanceof PendingIntentRecord)) {
   6660             return null;
   6661         }
   6662         try {
   6663             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6664             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   6665         } catch (ClassCastException e) {
   6666         }
   6667         return null;
   6668     }
   6669 
   6670     @Override
   6671     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   6672         if (!(pendingResult instanceof PendingIntentRecord)) {
   6673             return null;
   6674         }
   6675         try {
   6676             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6677             Intent intent = res.key.requestIntent;
   6678             if (intent != null) {
   6679                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   6680                         || res.lastTagPrefix.equals(prefix))) {
   6681                     return res.lastTag;
   6682                 }
   6683                 res.lastTagPrefix = prefix;
   6684                 StringBuilder sb = new StringBuilder(128);
   6685                 if (prefix != null) {
   6686                     sb.append(prefix);
   6687                 }
   6688                 if (intent.getAction() != null) {
   6689                     sb.append(intent.getAction());
   6690                 } else if (intent.getComponent() != null) {
   6691                     intent.getComponent().appendShortString(sb);
   6692                 } else {
   6693                     sb.append("?");
   6694                 }
   6695                 return res.lastTag = sb.toString();
   6696             }
   6697         } catch (ClassCastException e) {
   6698         }
   6699         return null;
   6700     }
   6701 
   6702     @Override
   6703     public void setProcessLimit(int max) {
   6704         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6705                 "setProcessLimit()");
   6706         synchronized (this) {
   6707             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   6708             mProcessLimitOverride = max;
   6709         }
   6710         trimApplications();
   6711     }
   6712 
   6713     @Override
   6714     public int getProcessLimit() {
   6715         synchronized (this) {
   6716             return mProcessLimitOverride;
   6717         }
   6718     }
   6719 
   6720     void foregroundTokenDied(ForegroundToken token) {
   6721         synchronized (ActivityManagerService.this) {
   6722             synchronized (mPidsSelfLocked) {
   6723                 ForegroundToken cur
   6724                     = mForegroundProcesses.get(token.pid);
   6725                 if (cur != token) {
   6726                     return;
   6727                 }
   6728                 mForegroundProcesses.remove(token.pid);
   6729                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   6730                 if (pr == null) {
   6731                     return;
   6732                 }
   6733                 pr.forcingToForeground = null;
   6734                 updateProcessForegroundLocked(pr, false, false);
   6735             }
   6736             updateOomAdjLocked();
   6737         }
   6738     }
   6739 
   6740     @Override
   6741     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   6742         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6743                 "setProcessForeground()");
   6744         synchronized(this) {
   6745             boolean changed = false;
   6746 
   6747             synchronized (mPidsSelfLocked) {
   6748                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   6749                 if (pr == null && isForeground) {
   6750                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   6751                     return;
   6752                 }
   6753                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   6754                 if (oldToken != null) {
   6755                     oldToken.token.unlinkToDeath(oldToken, 0);
   6756                     mForegroundProcesses.remove(pid);
   6757                     if (pr != null) {
   6758                         pr.forcingToForeground = null;
   6759                     }
   6760                     changed = true;
   6761                 }
   6762                 if (isForeground && token != null) {
   6763                     ForegroundToken newToken = new ForegroundToken() {
   6764                         @Override
   6765                         public void binderDied() {
   6766                             foregroundTokenDied(this);
   6767                         }
   6768                     };
   6769                     newToken.pid = pid;
   6770                     newToken.token = token;
   6771                     try {
   6772                         token.linkToDeath(newToken, 0);
   6773                         mForegroundProcesses.put(pid, newToken);
   6774                         pr.forcingToForeground = token;
   6775                         changed = true;
   6776                     } catch (RemoteException e) {
   6777                         // If the process died while doing this, we will later
   6778                         // do the cleanup with the process death link.
   6779                     }
   6780                 }
   6781             }
   6782 
   6783             if (changed) {
   6784                 updateOomAdjLocked();
   6785             }
   6786         }
   6787     }
   6788 
   6789     // =========================================================
   6790     // PERMISSIONS
   6791     // =========================================================
   6792 
   6793     static class PermissionController extends IPermissionController.Stub {
   6794         ActivityManagerService mActivityManagerService;
   6795         PermissionController(ActivityManagerService activityManagerService) {
   6796             mActivityManagerService = activityManagerService;
   6797         }
   6798 
   6799         @Override
   6800         public boolean checkPermission(String permission, int pid, int uid) {
   6801             return mActivityManagerService.checkPermission(permission, pid,
   6802                     uid) == PackageManager.PERMISSION_GRANTED;
   6803         }
   6804     }
   6805 
   6806     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   6807         @Override
   6808         public int checkComponentPermission(String permission, int pid, int uid,
   6809                 int owningUid, boolean exported) {
   6810             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   6811                     owningUid, exported);
   6812         }
   6813 
   6814         @Override
   6815         public Object getAMSLock() {
   6816             return ActivityManagerService.this;
   6817         }
   6818     }
   6819 
   6820     /**
   6821      * This can be called with or without the global lock held.
   6822      */
   6823     int checkComponentPermission(String permission, int pid, int uid,
   6824             int owningUid, boolean exported) {
   6825         if (pid == MY_PID) {
   6826             return PackageManager.PERMISSION_GRANTED;
   6827         }
   6828         return ActivityManager.checkComponentPermission(permission, uid,
   6829                 owningUid, exported);
   6830     }
   6831 
   6832     /**
   6833      * As the only public entry point for permissions checking, this method
   6834      * can enforce the semantic that requesting a check on a null global
   6835      * permission is automatically denied.  (Internally a null permission
   6836      * string is used when calling {@link #checkComponentPermission} in cases
   6837      * when only uid-based security is needed.)
   6838      *
   6839      * This can be called with or without the global lock held.
   6840      */
   6841     @Override
   6842     public int checkPermission(String permission, int pid, int uid) {
   6843         if (permission == null) {
   6844             return PackageManager.PERMISSION_DENIED;
   6845         }
   6846         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   6847     }
   6848 
   6849     @Override
   6850     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
   6851         if (permission == null) {
   6852             return PackageManager.PERMISSION_DENIED;
   6853         }
   6854 
   6855         // We might be performing an operation on behalf of an indirect binder
   6856         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   6857         // client identity accordingly before proceeding.
   6858         Identity tlsIdentity = sCallerIdentity.get();
   6859         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   6860             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   6861                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   6862             uid = tlsIdentity.uid;
   6863             pid = tlsIdentity.pid;
   6864         }
   6865 
   6866         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   6867     }
   6868 
   6869     /**
   6870      * Binder IPC calls go through the public entry point.
   6871      * This can be called with or without the global lock held.
   6872      */
   6873     int checkCallingPermission(String permission) {
   6874         return checkPermission(permission,
   6875                 Binder.getCallingPid(),
   6876                 UserHandle.getAppId(Binder.getCallingUid()));
   6877     }
   6878 
   6879     /**
   6880      * This can be called with or without the global lock held.
   6881      */
   6882     void enforceCallingPermission(String permission, String func) {
   6883         if (checkCallingPermission(permission)
   6884                 == PackageManager.PERMISSION_GRANTED) {
   6885             return;
   6886         }
   6887 
   6888         String msg = "Permission Denial: " + func + " from pid="
   6889                 + Binder.getCallingPid()
   6890                 + ", uid=" + Binder.getCallingUid()
   6891                 + " requires " + permission;
   6892         Slog.w(TAG, msg);
   6893         throw new SecurityException(msg);
   6894     }
   6895 
   6896     /**
   6897      * Determine if UID is holding permissions required to access {@link Uri} in
   6898      * the given {@link ProviderInfo}. Final permission checking is always done
   6899      * in {@link ContentProvider}.
   6900      */
   6901     private final boolean checkHoldingPermissionsLocked(
   6902             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   6903         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6904                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   6905         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   6906             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   6907                     != PERMISSION_GRANTED) {
   6908                 return false;
   6909             }
   6910         }
   6911         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   6912     }
   6913 
   6914     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   6915             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   6916         if (pi.applicationInfo.uid == uid) {
   6917             return true;
   6918         } else if (!pi.exported) {
   6919             return false;
   6920         }
   6921 
   6922         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   6923         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   6924         try {
   6925             // check if target holds top-level <provider> permissions
   6926             if (!readMet && pi.readPermission != null && considerUidPermissions
   6927                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   6928                 readMet = true;
   6929             }
   6930             if (!writeMet && pi.writePermission != null && considerUidPermissions
   6931                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   6932                 writeMet = true;
   6933             }
   6934 
   6935             // track if unprotected read/write is allowed; any denied
   6936             // <path-permission> below removes this ability
   6937             boolean allowDefaultRead = pi.readPermission == null;
   6938             boolean allowDefaultWrite = pi.writePermission == null;
   6939 
   6940             // check if target holds any <path-permission> that match uri
   6941             final PathPermission[] pps = pi.pathPermissions;
   6942             if (pps != null) {
   6943                 final String path = grantUri.uri.getPath();
   6944                 int i = pps.length;
   6945                 while (i > 0 && (!readMet || !writeMet)) {
   6946                     i--;
   6947                     PathPermission pp = pps[i];
   6948                     if (pp.match(path)) {
   6949                         if (!readMet) {
   6950                             final String pprperm = pp.getReadPermission();
   6951                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   6952                                     + pprperm + " for " + pp.getPath()
   6953                                     + ": match=" + pp.match(path)
   6954                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   6955                             if (pprperm != null) {
   6956                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   6957                                         == PERMISSION_GRANTED) {
   6958                                     readMet = true;
   6959                                 } else {
   6960                                     allowDefaultRead = false;
   6961                                 }
   6962                             }
   6963                         }
   6964                         if (!writeMet) {
   6965                             final String ppwperm = pp.getWritePermission();
   6966                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   6967                                     + ppwperm + " for " + pp.getPath()
   6968                                     + ": match=" + pp.match(path)
   6969                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   6970                             if (ppwperm != null) {
   6971                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   6972                                         == PERMISSION_GRANTED) {
   6973                                     writeMet = true;
   6974                                 } else {
   6975                                     allowDefaultWrite = false;
   6976                                 }
   6977                             }
   6978                         }
   6979                     }
   6980                 }
   6981             }
   6982 
   6983             // grant unprotected <provider> read/write, if not blocked by
   6984             // <path-permission> above
   6985             if (allowDefaultRead) readMet = true;
   6986             if (allowDefaultWrite) writeMet = true;
   6987 
   6988         } catch (RemoteException e) {
   6989             return false;
   6990         }
   6991 
   6992         return readMet && writeMet;
   6993     }
   6994 
   6995     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
   6996         ProviderInfo pi = null;
   6997         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   6998         if (cpr != null) {
   6999             pi = cpr.info;
   7000         } else {
   7001             try {
   7002                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7003                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
   7004             } catch (RemoteException ex) {
   7005             }
   7006         }
   7007         return pi;
   7008     }
   7009 
   7010     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7011         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7012         if (targetUris != null) {
   7013             return targetUris.get(grantUri);
   7014         }
   7015         return null;
   7016     }
   7017 
   7018     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7019             String targetPkg, int targetUid, GrantUri grantUri) {
   7020         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7021         if (targetUris == null) {
   7022             targetUris = Maps.newArrayMap();
   7023             mGrantedUriPermissions.put(targetUid, targetUris);
   7024         }
   7025 
   7026         UriPermission perm = targetUris.get(grantUri);
   7027         if (perm == null) {
   7028             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7029             targetUris.put(grantUri, perm);
   7030         }
   7031 
   7032         return perm;
   7033     }
   7034 
   7035     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7036             final int modeFlags) {
   7037         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7038         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7039                 : UriPermission.STRENGTH_OWNED;
   7040 
   7041         // Root gets to do everything.
   7042         if (uid == 0) {
   7043             return true;
   7044         }
   7045 
   7046         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7047         if (perms == null) return false;
   7048 
   7049         // First look for exact match
   7050         final UriPermission exactPerm = perms.get(grantUri);
   7051         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7052             return true;
   7053         }
   7054 
   7055         // No exact match, look for prefixes
   7056         final int N = perms.size();
   7057         for (int i = 0; i < N; i++) {
   7058             final UriPermission perm = perms.valueAt(i);
   7059             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7060                     && perm.getStrength(modeFlags) >= minStrength) {
   7061                 return true;
   7062             }
   7063         }
   7064 
   7065         return false;
   7066     }
   7067 
   7068     /**
   7069      * @param uri This uri must NOT contain an embedded userId.
   7070      * @param userId The userId in which the uri is to be resolved.
   7071      */
   7072     @Override
   7073     public int checkUriPermission(Uri uri, int pid, int uid,
   7074             final int modeFlags, int userId, IBinder callerToken) {
   7075         enforceNotIsolatedCaller("checkUriPermission");
   7076 
   7077         // Another redirected-binder-call permissions check as in
   7078         // {@link checkPermissionWithToken}.
   7079         Identity tlsIdentity = sCallerIdentity.get();
   7080         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
   7081             uid = tlsIdentity.uid;
   7082             pid = tlsIdentity.pid;
   7083         }
   7084 
   7085         // Our own process gets to do everything.
   7086         if (pid == MY_PID) {
   7087             return PackageManager.PERMISSION_GRANTED;
   7088         }
   7089         synchronized (this) {
   7090             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   7091                     ? PackageManager.PERMISSION_GRANTED
   7092                     : PackageManager.PERMISSION_DENIED;
   7093         }
   7094     }
   7095 
   7096     /**
   7097      * Check if the targetPkg can be granted permission to access uri by
   7098      * the callingUid using the given modeFlags.  Throws a security exception
   7099      * if callingUid is not allowed to do this.  Returns the uid of the target
   7100      * if the URI permission grant should be performed; returns -1 if it is not
   7101      * needed (for example targetPkg already has permission to access the URI).
   7102      * If you already know the uid of the target, you can supply it in
   7103      * lastTargetUid else set that to -1.
   7104      */
   7105     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7106             final int modeFlags, int lastTargetUid) {
   7107         if (!Intent.isAccessUriMode(modeFlags)) {
   7108             return -1;
   7109         }
   7110 
   7111         if (targetPkg != null) {
   7112             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7113                     "Checking grant " + targetPkg + " permission to " + grantUri);
   7114         }
   7115 
   7116         final IPackageManager pm = AppGlobals.getPackageManager();
   7117 
   7118         // If this is not a content: uri, we can't do anything with it.
   7119         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   7120             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7121                     "Can't grant URI permission for non-content URI: " + grantUri);
   7122             return -1;
   7123         }
   7124 
   7125         final String authority = grantUri.uri.getAuthority();
   7126         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7127         if (pi == null) {
   7128             Slog.w(TAG, "No content provider found for permission check: " +
   7129                     grantUri.uri.toSafeString());
   7130             return -1;
   7131         }
   7132 
   7133         int targetUid = lastTargetUid;
   7134         if (targetUid < 0 && targetPkg != null) {
   7135             try {
   7136                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   7137                 if (targetUid < 0) {
   7138                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7139                             "Can't grant URI permission no uid for: " + targetPkg);
   7140                     return -1;
   7141                 }
   7142             } catch (RemoteException ex) {
   7143                 return -1;
   7144             }
   7145         }
   7146 
   7147         if (targetUid >= 0) {
   7148             // First...  does the target actually need this permission?
   7149             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   7150                 // No need to grant the target this permission.
   7151                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7152                         "Target " + targetPkg + " already has full permission to " + grantUri);
   7153                 return -1;
   7154             }
   7155         } else {
   7156             // First...  there is no target package, so can anyone access it?
   7157             boolean allowed = pi.exported;
   7158             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   7159                 if (pi.readPermission != null) {
   7160                     allowed = false;
   7161                 }
   7162             }
   7163             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   7164                 if (pi.writePermission != null) {
   7165                     allowed = false;
   7166                 }
   7167             }
   7168             if (allowed) {
   7169                 return -1;
   7170             }
   7171         }
   7172 
   7173         /* There is a special cross user grant if:
   7174          * - The target is on another user.
   7175          * - Apps on the current user can access the uri without any uid permissions.
   7176          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   7177          * grant uri permissions.
   7178          */
   7179         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   7180                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   7181                 modeFlags, false /*without considering the uid permissions*/);
   7182 
   7183         // Second...  is the provider allowing granting of URI permissions?
   7184         if (!specialCrossUserGrant) {
   7185             if (!pi.grantUriPermissions) {
   7186                 throw new SecurityException("Provider " + pi.packageName
   7187                         + "/" + pi.name
   7188                         + " does not allow granting of Uri permissions (uri "
   7189                         + grantUri + ")");
   7190             }
   7191             if (pi.uriPermissionPatterns != null) {
   7192                 final int N = pi.uriPermissionPatterns.length;
   7193                 boolean allowed = false;
   7194                 for (int i=0; i<N; i++) {
   7195                     if (pi.uriPermissionPatterns[i] != null
   7196                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   7197                         allowed = true;
   7198                         break;
   7199                     }
   7200                 }
   7201                 if (!allowed) {
   7202                     throw new SecurityException("Provider " + pi.packageName
   7203                             + "/" + pi.name
   7204                             + " does not allow granting of permission to path of Uri "
   7205                             + grantUri);
   7206                 }
   7207             }
   7208         }
   7209 
   7210         // Third...  does the caller itself have permission to access
   7211         // this uri?
   7212         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   7213             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7214                 // Require they hold a strong enough Uri permission
   7215                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   7216                     throw new SecurityException("Uid " + callingUid
   7217                             + " does not have permission to uri " + grantUri);
   7218                 }
   7219             }
   7220         }
   7221         return targetUid;
   7222     }
   7223 
   7224     /**
   7225      * @param uri This uri must NOT contain an embedded userId.
   7226      * @param userId The userId in which the uri is to be resolved.
   7227      */
   7228     @Override
   7229     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   7230             final int modeFlags, int userId) {
   7231         enforceNotIsolatedCaller("checkGrantUriPermission");
   7232         synchronized(this) {
   7233             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   7234                     new GrantUri(userId, uri, false), modeFlags, -1);
   7235         }
   7236     }
   7237 
   7238     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   7239             final int modeFlags, UriPermissionOwner owner) {
   7240         if (!Intent.isAccessUriMode(modeFlags)) {
   7241             return;
   7242         }
   7243 
   7244         // So here we are: the caller has the assumed permission
   7245         // to the uri, and the target doesn't.  Let's now give this to
   7246         // the target.
   7247 
   7248         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7249                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   7250 
   7251         final String authority = grantUri.uri.getAuthority();
   7252         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7253         if (pi == null) {
   7254             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   7255             return;
   7256         }
   7257 
   7258         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   7259             grantUri.prefix = true;
   7260         }
   7261         final UriPermission perm = findOrCreateUriPermissionLocked(
   7262                 pi.packageName, targetPkg, targetUid, grantUri);
   7263         perm.grantModes(modeFlags, owner);
   7264     }
   7265 
   7266     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7267             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   7268         if (targetPkg == null) {
   7269             throw new NullPointerException("targetPkg");
   7270         }
   7271         int targetUid;
   7272         final IPackageManager pm = AppGlobals.getPackageManager();
   7273         try {
   7274             targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7275         } catch (RemoteException ex) {
   7276             return;
   7277         }
   7278 
   7279         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   7280                 targetUid);
   7281         if (targetUid < 0) {
   7282             return;
   7283         }
   7284 
   7285         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   7286                 owner);
   7287     }
   7288 
   7289     static class NeededUriGrants extends ArrayList<GrantUri> {
   7290         final String targetPkg;
   7291         final int targetUid;
   7292         final int flags;
   7293 
   7294         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   7295             this.targetPkg = targetPkg;
   7296             this.targetUid = targetUid;
   7297             this.flags = flags;
   7298         }
   7299     }
   7300 
   7301     /**
   7302      * Like checkGrantUriPermissionLocked, but takes an Intent.
   7303      */
   7304     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   7305             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   7306         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7307                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   7308                 + " clip=" + (intent != null ? intent.getClipData() : null)
   7309                 + " from " + intent + "; flags=0x"
   7310                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   7311 
   7312         if (targetPkg == null) {
   7313             throw new NullPointerException("targetPkg");
   7314         }
   7315 
   7316         if (intent == null) {
   7317             return null;
   7318         }
   7319         Uri data = intent.getData();
   7320         ClipData clip = intent.getClipData();
   7321         if (data == null && clip == null) {
   7322             return null;
   7323         }
   7324         // Default userId for uris in the intent (if they don't specify it themselves)
   7325         int contentUserHint = intent.getContentUserHint();
   7326         if (contentUserHint == UserHandle.USER_CURRENT) {
   7327             contentUserHint = UserHandle.getUserId(callingUid);
   7328         }
   7329         final IPackageManager pm = AppGlobals.getPackageManager();
   7330         int targetUid;
   7331         if (needed != null) {
   7332             targetUid = needed.targetUid;
   7333         } else {
   7334             try {
   7335                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7336             } catch (RemoteException ex) {
   7337                 return null;
   7338             }
   7339             if (targetUid < 0) {
   7340                 if (DEBUG_URI_PERMISSION) {
   7341                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
   7342                             + " on user " + targetUserId);
   7343                 }
   7344                 return null;
   7345             }
   7346         }
   7347         if (data != null) {
   7348             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   7349             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7350                     targetUid);
   7351             if (targetUid > 0) {
   7352                 if (needed == null) {
   7353                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7354                 }
   7355                 needed.add(grantUri);
   7356             }
   7357         }
   7358         if (clip != null) {
   7359             for (int i=0; i<clip.getItemCount(); i++) {
   7360                 Uri uri = clip.getItemAt(i).getUri();
   7361                 if (uri != null) {
   7362                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   7363                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7364                             targetUid);
   7365                     if (targetUid > 0) {
   7366                         if (needed == null) {
   7367                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7368                         }
   7369                         needed.add(grantUri);
   7370                     }
   7371                 } else {
   7372                     Intent clipIntent = clip.getItemAt(i).getIntent();
   7373                     if (clipIntent != null) {
   7374                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   7375                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   7376                         if (newNeeded != null) {
   7377                             needed = newNeeded;
   7378                         }
   7379                     }
   7380                 }
   7381             }
   7382         }
   7383 
   7384         return needed;
   7385     }
   7386 
   7387     /**
   7388      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   7389      */
   7390     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   7391             UriPermissionOwner owner) {
   7392         if (needed != null) {
   7393             for (int i=0; i<needed.size(); i++) {
   7394                 GrantUri grantUri = needed.get(i);
   7395                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   7396                         grantUri, needed.flags, owner);
   7397             }
   7398         }
   7399     }
   7400 
   7401     void grantUriPermissionFromIntentLocked(int callingUid,
   7402             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   7403         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   7404                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   7405         if (needed == null) {
   7406             return;
   7407         }
   7408 
   7409         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   7410     }
   7411 
   7412     /**
   7413      * @param uri This uri must NOT contain an embedded userId.
   7414      * @param userId The userId in which the uri is to be resolved.
   7415      */
   7416     @Override
   7417     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   7418             final int modeFlags, int userId) {
   7419         enforceNotIsolatedCaller("grantUriPermission");
   7420         GrantUri grantUri = new GrantUri(userId, uri, false);
   7421         synchronized(this) {
   7422             final ProcessRecord r = getRecordForAppLocked(caller);
   7423             if (r == null) {
   7424                 throw new SecurityException("Unable to find app for caller "
   7425                         + caller
   7426                         + " when granting permission to uri " + grantUri);
   7427             }
   7428             if (targetPkg == null) {
   7429                 throw new IllegalArgumentException("null target");
   7430             }
   7431             if (grantUri == null) {
   7432                 throw new IllegalArgumentException("null uri");
   7433             }
   7434 
   7435             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   7436                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   7437                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   7438                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   7439 
   7440             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   7441                     UserHandle.getUserId(r.uid));
   7442         }
   7443     }
   7444 
   7445     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   7446         if (perm.modeFlags == 0) {
   7447             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   7448                     perm.targetUid);
   7449             if (perms != null) {
   7450                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7451                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   7452 
   7453                 perms.remove(perm.uri);
   7454                 if (perms.isEmpty()) {
   7455                     mGrantedUriPermissions.remove(perm.targetUid);
   7456                 }
   7457             }
   7458         }
   7459     }
   7460 
   7461     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   7462         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
   7463 
   7464         final IPackageManager pm = AppGlobals.getPackageManager();
   7465         final String authority = grantUri.uri.getAuthority();
   7466         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7467         if (pi == null) {
   7468             Slog.w(TAG, "No content provider found for permission revoke: "
   7469                     + grantUri.toSafeString());
   7470             return;
   7471         }
   7472 
   7473         // Does the caller have this permission on the URI?
   7474         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7475             // If they don't have direct access to the URI, then revoke any
   7476             // ownerless URI permissions that have been granted to them.
   7477             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   7478             if (perms != null) {
   7479                 boolean persistChanged = false;
   7480                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7481                     final UriPermission perm = it.next();
   7482                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   7483                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   7484                         if (DEBUG_URI_PERMISSION)
   7485                             Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
   7486                                     " permission to " + perm.uri);
   7487                         persistChanged |= perm.revokeModes(
   7488                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   7489                         if (perm.modeFlags == 0) {
   7490                             it.remove();
   7491                         }
   7492                     }
   7493                 }
   7494                 if (perms.isEmpty()) {
   7495                     mGrantedUriPermissions.remove(callingUid);
   7496                 }
   7497                 if (persistChanged) {
   7498                     schedulePersistUriGrants();
   7499                 }
   7500             }
   7501             return;
   7502         }
   7503 
   7504         boolean persistChanged = false;
   7505 
   7506         // Go through all of the permissions and remove any that match.
   7507         int N = mGrantedUriPermissions.size();
   7508         for (int i = 0; i < N; i++) {
   7509             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7510             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7511 
   7512             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7513                 final UriPermission perm = it.next();
   7514                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   7515                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   7516                     if (DEBUG_URI_PERMISSION)
   7517                         Slog.v(TAG,
   7518                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   7519                     persistChanged |= perm.revokeModes(
   7520                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7521                     if (perm.modeFlags == 0) {
   7522                         it.remove();
   7523                     }
   7524                 }
   7525             }
   7526 
   7527             if (perms.isEmpty()) {
   7528                 mGrantedUriPermissions.remove(targetUid);
   7529                 N--;
   7530                 i--;
   7531             }
   7532         }
   7533 
   7534         if (persistChanged) {
   7535             schedulePersistUriGrants();
   7536         }
   7537     }
   7538 
   7539     /**
   7540      * @param uri This uri must NOT contain an embedded userId.
   7541      * @param userId The userId in which the uri is to be resolved.
   7542      */
   7543     @Override
   7544     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   7545             int userId) {
   7546         enforceNotIsolatedCaller("revokeUriPermission");
   7547         synchronized(this) {
   7548             final ProcessRecord r = getRecordForAppLocked(caller);
   7549             if (r == null) {
   7550                 throw new SecurityException("Unable to find app for caller "
   7551                         + caller
   7552                         + " when revoking permission to uri " + uri);
   7553             }
   7554             if (uri == null) {
   7555                 Slog.w(TAG, "revokeUriPermission: null uri");
   7556                 return;
   7557             }
   7558 
   7559             if (!Intent.isAccessUriMode(modeFlags)) {
   7560                 return;
   7561             }
   7562 
   7563             final IPackageManager pm = AppGlobals.getPackageManager();
   7564             final String authority = uri.getAuthority();
   7565             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
   7566             if (pi == null) {
   7567                 Slog.w(TAG, "No content provider found for permission revoke: "
   7568                         + uri.toSafeString());
   7569                 return;
   7570             }
   7571 
   7572             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   7573         }
   7574     }
   7575 
   7576     /**
   7577      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   7578      * given package.
   7579      *
   7580      * @param packageName Package name to match, or {@code null} to apply to all
   7581      *            packages.
   7582      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   7583      *            to all users.
   7584      * @param persistable If persistable grants should be removed.
   7585      */
   7586     private void removeUriPermissionsForPackageLocked(
   7587             String packageName, int userHandle, boolean persistable) {
   7588         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   7589             throw new IllegalArgumentException("Must narrow by either package or user");
   7590         }
   7591 
   7592         boolean persistChanged = false;
   7593 
   7594         int N = mGrantedUriPermissions.size();
   7595         for (int i = 0; i < N; i++) {
   7596             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7597             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7598 
   7599             // Only inspect grants matching user
   7600             if (userHandle == UserHandle.USER_ALL
   7601                     || userHandle == UserHandle.getUserId(targetUid)) {
   7602                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7603                     final UriPermission perm = it.next();
   7604 
   7605                     // Only inspect grants matching package
   7606                     if (packageName == null || perm.sourcePkg.equals(packageName)
   7607                             || perm.targetPkg.equals(packageName)) {
   7608                         persistChanged |= perm.revokeModes(persistable
   7609                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7610 
   7611                         // Only remove when no modes remain; any persisted grants
   7612                         // will keep this alive.
   7613                         if (perm.modeFlags == 0) {
   7614                             it.remove();
   7615                         }
   7616                     }
   7617                 }
   7618 
   7619                 if (perms.isEmpty()) {
   7620                     mGrantedUriPermissions.remove(targetUid);
   7621                     N--;
   7622                     i--;
   7623                 }
   7624             }
   7625         }
   7626 
   7627         if (persistChanged) {
   7628             schedulePersistUriGrants();
   7629         }
   7630     }
   7631 
   7632     @Override
   7633     public IBinder newUriPermissionOwner(String name) {
   7634         enforceNotIsolatedCaller("newUriPermissionOwner");
   7635         synchronized(this) {
   7636             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   7637             return owner.getExternalTokenLocked();
   7638         }
   7639     }
   7640 
   7641     /**
   7642      * @param uri This uri must NOT contain an embedded userId.
   7643      * @param sourceUserId The userId in which the uri is to be resolved.
   7644      * @param targetUserId The userId of the app that receives the grant.
   7645      */
   7646     @Override
   7647     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   7648             final int modeFlags, int sourceUserId, int targetUserId) {
   7649         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   7650                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
   7651         synchronized(this) {
   7652             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7653             if (owner == null) {
   7654                 throw new IllegalArgumentException("Unknown owner: " + token);
   7655             }
   7656             if (fromUid != Binder.getCallingUid()) {
   7657                 if (Binder.getCallingUid() != Process.myUid()) {
   7658                     // Only system code can grant URI permissions on behalf
   7659                     // of other users.
   7660                     throw new SecurityException("nice try");
   7661                 }
   7662             }
   7663             if (targetPkg == null) {
   7664                 throw new IllegalArgumentException("null target");
   7665             }
   7666             if (uri == null) {
   7667                 throw new IllegalArgumentException("null uri");
   7668             }
   7669 
   7670             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   7671                     modeFlags, owner, targetUserId);
   7672         }
   7673     }
   7674 
   7675     /**
   7676      * @param uri This uri must NOT contain an embedded userId.
   7677      * @param userId The userId in which the uri is to be resolved.
   7678      */
   7679     @Override
   7680     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   7681         synchronized(this) {
   7682             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7683             if (owner == null) {
   7684                 throw new IllegalArgumentException("Unknown owner: " + token);
   7685             }
   7686 
   7687             if (uri == null) {
   7688                 owner.removeUriPermissionsLocked(mode);
   7689             } else {
   7690                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
   7691             }
   7692         }
   7693     }
   7694 
   7695     private void schedulePersistUriGrants() {
   7696         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   7697             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   7698                     10 * DateUtils.SECOND_IN_MILLIS);
   7699         }
   7700     }
   7701 
   7702     private void writeGrantedUriPermissions() {
   7703         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
   7704 
   7705         // Snapshot permissions so we can persist without lock
   7706         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   7707         synchronized (this) {
   7708             final int size = mGrantedUriPermissions.size();
   7709             for (int i = 0; i < size; i++) {
   7710                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7711                 for (UriPermission perm : perms.values()) {
   7712                     if (perm.persistedModeFlags != 0) {
   7713                         persist.add(perm.snapshot());
   7714                     }
   7715                 }
   7716             }
   7717         }
   7718 
   7719         FileOutputStream fos = null;
   7720         try {
   7721             fos = mGrantFile.startWrite();
   7722 
   7723             XmlSerializer out = new FastXmlSerializer();
   7724             out.setOutput(fos, "utf-8");
   7725             out.startDocument(null, true);
   7726             out.startTag(null, TAG_URI_GRANTS);
   7727             for (UriPermission.Snapshot perm : persist) {
   7728                 out.startTag(null, TAG_URI_GRANT);
   7729                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   7730                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   7731                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   7732                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   7733                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   7734                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   7735                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   7736                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   7737                 out.endTag(null, TAG_URI_GRANT);
   7738             }
   7739             out.endTag(null, TAG_URI_GRANTS);
   7740             out.endDocument();
   7741 
   7742             mGrantFile.finishWrite(fos);
   7743         } catch (IOException e) {
   7744             if (fos != null) {
   7745                 mGrantFile.failWrite(fos);
   7746             }
   7747         }
   7748     }
   7749 
   7750     private void readGrantedUriPermissionsLocked() {
   7751         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
   7752 
   7753         final long now = System.currentTimeMillis();
   7754 
   7755         FileInputStream fis = null;
   7756         try {
   7757             fis = mGrantFile.openRead();
   7758             final XmlPullParser in = Xml.newPullParser();
   7759             in.setInput(fis, null);
   7760 
   7761             int type;
   7762             while ((type = in.next()) != END_DOCUMENT) {
   7763                 final String tag = in.getName();
   7764                 if (type == START_TAG) {
   7765                     if (TAG_URI_GRANT.equals(tag)) {
   7766                         final int sourceUserId;
   7767                         final int targetUserId;
   7768                         final int userHandle = readIntAttribute(in,
   7769                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   7770                         if (userHandle != UserHandle.USER_NULL) {
   7771                             // For backwards compatibility.
   7772                             sourceUserId = userHandle;
   7773                             targetUserId = userHandle;
   7774                         } else {
   7775                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   7776                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   7777                         }
   7778                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   7779                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   7780                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   7781                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   7782                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   7783                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   7784 
   7785                         // Sanity check that provider still belongs to source package
   7786                         final ProviderInfo pi = getProviderInfoLocked(
   7787                                 uri.getAuthority(), sourceUserId);
   7788                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   7789                             int targetUid = -1;
   7790                             try {
   7791                                 targetUid = AppGlobals.getPackageManager()
   7792                                         .getPackageUid(targetPkg, targetUserId);
   7793                             } catch (RemoteException e) {
   7794                             }
   7795                             if (targetUid != -1) {
   7796                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   7797                                         sourcePkg, targetPkg, targetUid,
   7798                                         new GrantUri(sourceUserId, uri, prefix));
   7799                                 perm.initPersistedModes(modeFlags, createdTime);
   7800                             }
   7801                         } else {
   7802                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   7803                                     + " but instead found " + pi);
   7804                         }
   7805                     }
   7806                 }
   7807             }
   7808         } catch (FileNotFoundException e) {
   7809             // Missing grants is okay
   7810         } catch (IOException e) {
   7811             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7812         } catch (XmlPullParserException e) {
   7813             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7814         } finally {
   7815             IoUtils.closeQuietly(fis);
   7816         }
   7817     }
   7818 
   7819     /**
   7820      * @param uri This uri must NOT contain an embedded userId.
   7821      * @param userId The userId in which the uri is to be resolved.
   7822      */
   7823     @Override
   7824     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7825         enforceNotIsolatedCaller("takePersistableUriPermission");
   7826 
   7827         Preconditions.checkFlagsArgument(modeFlags,
   7828                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7829 
   7830         synchronized (this) {
   7831             final int callingUid = Binder.getCallingUid();
   7832             boolean persistChanged = false;
   7833             GrantUri grantUri = new GrantUri(userId, uri, false);
   7834 
   7835             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   7836                     new GrantUri(userId, uri, false));
   7837             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   7838                     new GrantUri(userId, uri, true));
   7839 
   7840             final boolean exactValid = (exactPerm != null)
   7841                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   7842             final boolean prefixValid = (prefixPerm != null)
   7843                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   7844 
   7845             if (!(exactValid || prefixValid)) {
   7846                 throw new SecurityException("No persistable permission grants found for UID "
   7847                         + callingUid + " and Uri " + grantUri.toSafeString());
   7848             }
   7849 
   7850             if (exactValid) {
   7851                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   7852             }
   7853             if (prefixValid) {
   7854                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   7855             }
   7856 
   7857             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   7858 
   7859             if (persistChanged) {
   7860                 schedulePersistUriGrants();
   7861             }
   7862         }
   7863     }
   7864 
   7865     /**
   7866      * @param uri This uri must NOT contain an embedded userId.
   7867      * @param userId The userId in which the uri is to be resolved.
   7868      */
   7869     @Override
   7870     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7871         enforceNotIsolatedCaller("releasePersistableUriPermission");
   7872 
   7873         Preconditions.checkFlagsArgument(modeFlags,
   7874                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7875 
   7876         synchronized (this) {
   7877             final int callingUid = Binder.getCallingUid();
   7878             boolean persistChanged = false;
   7879 
   7880             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   7881                     new GrantUri(userId, uri, false));
   7882             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   7883                     new GrantUri(userId, uri, true));
   7884             if (exactPerm == null && prefixPerm == null) {
   7885                 throw new SecurityException("No permission grants found for UID " + callingUid
   7886                         + " and Uri " + uri.toSafeString());
   7887             }
   7888 
   7889             if (exactPerm != null) {
   7890                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   7891                 removeUriPermissionIfNeededLocked(exactPerm);
   7892             }
   7893             if (prefixPerm != null) {
   7894                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   7895                 removeUriPermissionIfNeededLocked(prefixPerm);
   7896             }
   7897 
   7898             if (persistChanged) {
   7899                 schedulePersistUriGrants();
   7900             }
   7901         }
   7902     }
   7903 
   7904     /**
   7905      * Prune any older {@link UriPermission} for the given UID until outstanding
   7906      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   7907      *
   7908      * @return if any mutations occured that require persisting.
   7909      */
   7910     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   7911         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7912         if (perms == null) return false;
   7913         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   7914 
   7915         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   7916         for (UriPermission perm : perms.values()) {
   7917             if (perm.persistedModeFlags != 0) {
   7918                 persisted.add(perm);
   7919             }
   7920         }
   7921 
   7922         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   7923         if (trimCount <= 0) return false;
   7924 
   7925         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   7926         for (int i = 0; i < trimCount; i++) {
   7927             final UriPermission perm = persisted.get(i);
   7928 
   7929             if (DEBUG_URI_PERMISSION) {
   7930                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
   7931             }
   7932 
   7933             perm.releasePersistableModes(~0);
   7934             removeUriPermissionIfNeededLocked(perm);
   7935         }
   7936 
   7937         return true;
   7938     }
   7939 
   7940     @Override
   7941     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   7942             String packageName, boolean incoming) {
   7943         enforceNotIsolatedCaller("getPersistedUriPermissions");
   7944         Preconditions.checkNotNull(packageName, "packageName");
   7945 
   7946         final int callingUid = Binder.getCallingUid();
   7947         final IPackageManager pm = AppGlobals.getPackageManager();
   7948         try {
   7949             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
   7950             if (packageUid != callingUid) {
   7951                 throw new SecurityException(
   7952                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   7953             }
   7954         } catch (RemoteException e) {
   7955             throw new SecurityException("Failed to verify package name ownership");
   7956         }
   7957 
   7958         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   7959         synchronized (this) {
   7960             if (incoming) {
   7961                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   7962                         callingUid);
   7963                 if (perms == null) {
   7964                     Slog.w(TAG, "No permission grants found for " + packageName);
   7965                 } else {
   7966                     for (UriPermission perm : perms.values()) {
   7967                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   7968                             result.add(perm.buildPersistedPublicApiObject());
   7969                         }
   7970                     }
   7971                 }
   7972             } else {
   7973                 final int size = mGrantedUriPermissions.size();
   7974                 for (int i = 0; i < size; i++) {
   7975                     final ArrayMap<GrantUri, UriPermission> perms =
   7976                             mGrantedUriPermissions.valueAt(i);
   7977                     for (UriPermission perm : perms.values()) {
   7978                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   7979                             result.add(perm.buildPersistedPublicApiObject());
   7980                         }
   7981                     }
   7982                 }
   7983             }
   7984         }
   7985         return new ParceledListSlice<android.content.UriPermission>(result);
   7986     }
   7987 
   7988     @Override
   7989     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   7990         synchronized (this) {
   7991             ProcessRecord app =
   7992                 who != null ? getRecordForAppLocked(who) : null;
   7993             if (app == null) return;
   7994 
   7995             Message msg = Message.obtain();
   7996             msg.what = WAIT_FOR_DEBUGGER_MSG;
   7997             msg.obj = app;
   7998             msg.arg1 = waiting ? 1 : 0;
   7999             mHandler.sendMessage(msg);
   8000         }
   8001     }
   8002 
   8003     @Override
   8004     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8005         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8006         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8007         outInfo.availMem = Process.getFreeMemory();
   8008         outInfo.totalMem = Process.getTotalMemory();
   8009         outInfo.threshold = homeAppMem;
   8010         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   8011         outInfo.hiddenAppThreshold = cachedAppMem;
   8012         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   8013                 ProcessList.SERVICE_ADJ);
   8014         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   8015                 ProcessList.VISIBLE_APP_ADJ);
   8016         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   8017                 ProcessList.FOREGROUND_APP_ADJ);
   8018     }
   8019 
   8020     // =========================================================
   8021     // TASK MANAGEMENT
   8022     // =========================================================
   8023 
   8024     @Override
   8025     public List<IAppTask> getAppTasks(String callingPackage) {
   8026         int callingUid = Binder.getCallingUid();
   8027         long ident = Binder.clearCallingIdentity();
   8028 
   8029         synchronized(this) {
   8030             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   8031             try {
   8032                 if (localLOGV) Slog.v(TAG, "getAppTasks");
   8033 
   8034                 final int N = mRecentTasks.size();
   8035                 for (int i = 0; i < N; i++) {
   8036                     TaskRecord tr = mRecentTasks.get(i);
   8037                     // Skip tasks that do not match the caller.  We don't need to verify
   8038                     // callingPackage, because we are also limiting to callingUid and know
   8039                     // that will limit to the correct security sandbox.
   8040                     if (tr.effectiveUid != callingUid) {
   8041                         continue;
   8042                     }
   8043                     Intent intent = tr.getBaseIntent();
   8044                     if (intent == null ||
   8045                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   8046                         continue;
   8047                     }
   8048                     ActivityManager.RecentTaskInfo taskInfo =
   8049                             createRecentTaskInfoFromTaskRecord(tr);
   8050                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   8051                     list.add(taskImpl);
   8052                 }
   8053             } finally {
   8054                 Binder.restoreCallingIdentity(ident);
   8055             }
   8056             return list;
   8057         }
   8058     }
   8059 
   8060     @Override
   8061     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   8062         final int callingUid = Binder.getCallingUid();
   8063         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   8064 
   8065         synchronized(this) {
   8066             if (localLOGV) Slog.v(
   8067                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   8068 
   8069             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   8070                     callingUid);
   8071 
   8072             // TODO: Improve with MRU list from all ActivityStacks.
   8073             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   8074         }
   8075 
   8076         return list;
   8077     }
   8078 
   8079     /**
   8080      * Creates a new RecentTaskInfo from a TaskRecord.
   8081      */
   8082     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   8083         // Update the task description to reflect any changes in the task stack
   8084         tr.updateTaskDescription();
   8085 
   8086         // Compose the recent task info
   8087         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   8088         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
   8089         rti.persistentId = tr.taskId;
   8090         rti.baseIntent = new Intent(tr.getBaseIntent());
   8091         rti.origActivity = tr.origActivity;
   8092         rti.description = tr.lastDescription;
   8093         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   8094         rti.userId = tr.userId;
   8095         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   8096         rti.firstActiveTime = tr.firstActiveTime;
   8097         rti.lastActiveTime = tr.lastActiveTime;
   8098         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   8099         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   8100         return rti;
   8101     }
   8102 
   8103     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   8104         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   8105                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   8106         if (!allowed) {
   8107             if (checkPermission(android.Manifest.permission.GET_TASKS,
   8108                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   8109                 // Temporary compatibility: some existing apps on the system image may
   8110                 // still be requesting the old permission and not switched to the new
   8111                 // one; if so, we'll still allow them full access.  This means we need
   8112                 // to see if they are holding the old permission and are a system app.
   8113                 try {
   8114                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   8115                         allowed = true;
   8116                         Slog.w(TAG, caller + ": caller " + callingUid
   8117                                 + " is using old GET_TASKS but privileged; allowing");
   8118                     }
   8119                 } catch (RemoteException e) {
   8120                 }
   8121             }
   8122         }
   8123         if (!allowed) {
   8124             Slog.w(TAG, caller + ": caller " + callingUid
   8125                     + " does not hold GET_TASKS; limiting output");
   8126         }
   8127         return allowed;
   8128     }
   8129 
   8130     @Override
   8131     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
   8132         final int callingUid = Binder.getCallingUid();
   8133         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   8134                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   8135 
   8136         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   8137         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   8138         synchronized (this) {
   8139             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   8140                     callingUid);
   8141             final boolean detailed = checkCallingPermission(
   8142                     android.Manifest.permission.GET_DETAILED_TASKS)
   8143                     == PackageManager.PERMISSION_GRANTED;
   8144 
   8145             final int N = mRecentTasks.size();
   8146             ArrayList<ActivityManager.RecentTaskInfo> res
   8147                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   8148                             maxNum < N ? maxNum : N);
   8149 
   8150             final Set<Integer> includedUsers;
   8151             if (includeProfiles) {
   8152                 includedUsers = getProfileIdsLocked(userId);
   8153             } else {
   8154                 includedUsers = new HashSet<Integer>();
   8155             }
   8156             includedUsers.add(Integer.valueOf(userId));
   8157 
   8158             for (int i=0; i<N && maxNum > 0; i++) {
   8159                 TaskRecord tr = mRecentTasks.get(i);
   8160                 // Only add calling user or related users recent tasks
   8161                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   8162                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
   8163                     continue;
   8164                 }
   8165 
   8166                 // Return the entry if desired by the caller.  We always return
   8167                 // the first entry, because callers always expect this to be the
   8168                 // foreground app.  We may filter others if the caller has
   8169                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   8170                 // we should exclude the entry.
   8171 
   8172                 if (i == 0
   8173                         || withExcluded
   8174                         || (tr.intent == null)
   8175                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   8176                                 == 0)) {
   8177                     if (!allowed) {
   8178                         // If the caller doesn't have the GET_TASKS permission, then only
   8179                         // allow them to see a small subset of tasks -- their own and home.
   8180                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   8181                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
   8182                             continue;
   8183                         }
   8184                     }
   8185                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   8186                         if (tr.stack != null && tr.stack.isHomeStack()) {
   8187                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
   8188                             continue;
   8189                         }
   8190                     }
   8191                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   8192                         // Don't include auto remove tasks that are finished or finishing.
   8193                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
   8194                                 + tr);
   8195                         continue;
   8196                     }
   8197                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   8198                             && !tr.isAvailable) {
   8199                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
   8200                         continue;
   8201                     }
   8202 
   8203                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   8204                     if (!detailed) {
   8205                         rti.baseIntent.replaceExtras((Bundle)null);
   8206                     }
   8207 
   8208                     res.add(rti);
   8209                     maxNum--;
   8210                 }
   8211             }
   8212             return res;
   8213         }
   8214     }
   8215 
   8216     TaskRecord recentTaskForIdLocked(int id) {
   8217         final int N = mRecentTasks.size();
   8218             for (int i=0; i<N; i++) {
   8219                 TaskRecord tr = mRecentTasks.get(i);
   8220                 if (tr.taskId == id) {
   8221                     return tr;
   8222                 }
   8223             }
   8224             return null;
   8225     }
   8226 
   8227     @Override
   8228     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   8229         synchronized (this) {
   8230             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   8231                     "getTaskThumbnail()");
   8232             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
   8233             if (tr != null) {
   8234                 return tr.getTaskThumbnailLocked();
   8235             }
   8236         }
   8237         return null;
   8238     }
   8239 
   8240     @Override
   8241     public int addAppTask(IBinder activityToken, Intent intent,
   8242             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   8243         final int callingUid = Binder.getCallingUid();
   8244         final long callingIdent = Binder.clearCallingIdentity();
   8245 
   8246         try {
   8247             synchronized (this) {
   8248                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8249                 if (r == null) {
   8250                     throw new IllegalArgumentException("Activity does not exist; token="
   8251                             + activityToken);
   8252                 }
   8253                 ComponentName comp = intent.getComponent();
   8254                 if (comp == null) {
   8255                     throw new IllegalArgumentException("Intent " + intent
   8256                             + " must specify explicit component");
   8257                 }
   8258                 if (thumbnail.getWidth() != mThumbnailWidth
   8259                         || thumbnail.getHeight() != mThumbnailHeight) {
   8260                     throw new IllegalArgumentException("Bad thumbnail size: got "
   8261                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   8262                             + mThumbnailWidth + "x" + mThumbnailHeight);
   8263                 }
   8264                 if (intent.getSelector() != null) {
   8265                     intent.setSelector(null);
   8266                 }
   8267                 if (intent.getSourceBounds() != null) {
   8268                     intent.setSourceBounds(null);
   8269                 }
   8270                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   8271                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   8272                         // The caller has added this as an auto-remove task...  that makes no
   8273                         // sense, so turn off auto-remove.
   8274                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   8275                     }
   8276                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   8277                     // Must be a new task.
   8278                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8279                 }
   8280                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   8281                     mLastAddedTaskActivity = null;
   8282                 }
   8283                 ActivityInfo ainfo = mLastAddedTaskActivity;
   8284                 if (ainfo == null) {
   8285                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   8286                             comp, 0, UserHandle.getUserId(callingUid));
   8287                     if (ainfo.applicationInfo.uid != callingUid) {
   8288                         throw new SecurityException(
   8289                                 "Can't add task for another application: target uid="
   8290                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   8291                     }
   8292                 }
   8293 
   8294                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
   8295                         intent, description);
   8296 
   8297                 int trimIdx = trimRecentsForTaskLocked(task, false);
   8298                 if (trimIdx >= 0) {
   8299                     // If this would have caused a trim, then we'll abort because that
   8300                     // means it would be added at the end of the list but then just removed.
   8301                     return INVALID_TASK_ID;
   8302                 }
   8303 
   8304                 final int N = mRecentTasks.size();
   8305                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   8306                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   8307                     tr.removedFromRecents();
   8308                 }
   8309 
   8310                 task.inRecents = true;
   8311                 mRecentTasks.add(task);
   8312                 r.task.stack.addTask(task, false, false);
   8313 
   8314                 task.setLastThumbnail(thumbnail);
   8315                 task.freeLastThumbnail();
   8316 
   8317                 return task.taskId;
   8318             }
   8319         } finally {
   8320             Binder.restoreCallingIdentity(callingIdent);
   8321         }
   8322     }
   8323 
   8324     @Override
   8325     public Point getAppTaskThumbnailSize() {
   8326         synchronized (this) {
   8327             return new Point(mThumbnailWidth,  mThumbnailHeight);
   8328         }
   8329     }
   8330 
   8331     @Override
   8332     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   8333         synchronized (this) {
   8334             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8335             if (r != null) {
   8336                 r.setTaskDescription(td);
   8337                 r.task.updateTaskDescription();
   8338             }
   8339         }
   8340     }
   8341 
   8342     @Override
   8343     public Bitmap getTaskDescriptionIcon(String filename) {
   8344         if (!FileUtils.isValidExtFilename(filename)
   8345                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   8346             throw new IllegalArgumentException("Bad filename: " + filename);
   8347         }
   8348         return mTaskPersister.getTaskDescriptionIcon(filename);
   8349     }
   8350 
   8351     @Override
   8352     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
   8353             throws RemoteException {
   8354         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
   8355                 opts.getCustomInPlaceResId() == 0) {
   8356             throw new IllegalArgumentException("Expected in-place ActivityOption " +
   8357                     "with valid animation");
   8358         }
   8359         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
   8360         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
   8361                 opts.getCustomInPlaceResId());
   8362         mWindowManager.executeAppTransition();
   8363     }
   8364 
   8365     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
   8366         mRecentTasks.remove(tr);
   8367         tr.removedFromRecents();
   8368         ComponentName component = tr.getBaseIntent().getComponent();
   8369         if (component == null) {
   8370             Slog.w(TAG, "No component for base intent of task: " + tr);
   8371             return;
   8372         }
   8373 
   8374         if (!killProcess) {
   8375             return;
   8376         }
   8377 
   8378         // Determine if the process(es) for this task should be killed.
   8379         final String pkg = component.getPackageName();
   8380         ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
   8381         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   8382         for (int i = 0; i < pmap.size(); i++) {
   8383 
   8384             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   8385             for (int j = 0; j < uids.size(); j++) {
   8386                 ProcessRecord proc = uids.valueAt(j);
   8387                 if (proc.userId != tr.userId) {
   8388                     // Don't kill process for a different user.
   8389                     continue;
   8390                 }
   8391                 if (proc == mHomeProcess) {
   8392                     // Don't kill the home process along with tasks from the same package.
   8393                     continue;
   8394                 }
   8395                 if (!proc.pkgList.containsKey(pkg)) {
   8396                     // Don't kill process that is not associated with this task.
   8397                     continue;
   8398                 }
   8399 
   8400                 for (int k = 0; k < proc.activities.size(); k++) {
   8401                     TaskRecord otherTask = proc.activities.get(k).task;
   8402                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
   8403                         // Don't kill process(es) that has an activity in a different task that is
   8404                         // also in recents.
   8405                         return;
   8406                     }
   8407                 }
   8408 
   8409                 // Add process to kill list.
   8410                 procsToKill.add(proc);
   8411             }
   8412         }
   8413 
   8414         // Find any running services associated with this app and stop if needed.
   8415         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
   8416 
   8417         // Kill the running processes.
   8418         for (int i = 0; i < procsToKill.size(); i++) {
   8419             ProcessRecord pr = procsToKill.get(i);
   8420             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   8421                 pr.kill("remove task", true);
   8422             } else {
   8423                 pr.waitingToKill = "remove task";
   8424             }
   8425         }
   8426     }
   8427 
   8428     private void removeTasksByPackageNameLocked(String packageName, int userId) {
   8429         // Remove all tasks with activities in the specified package from the list of recent tasks
   8430         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   8431             TaskRecord tr = mRecentTasks.get(i);
   8432             if (tr.userId != userId) continue;
   8433 
   8434             ComponentName cn = tr.intent.getComponent();
   8435             if (cn != null && cn.getPackageName().equals(packageName)) {
   8436                 // If the package name matches, remove the task.
   8437                 removeTaskByIdLocked(tr.taskId, true);
   8438             }
   8439         }
   8440     }
   8441 
   8442     private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
   8443         final IPackageManager pm = AppGlobals.getPackageManager();
   8444         final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
   8445 
   8446         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   8447             TaskRecord tr = mRecentTasks.get(i);
   8448             if (tr.userId != userId) continue;
   8449 
   8450             ComponentName cn = tr.intent.getComponent();
   8451             if (cn != null && cn.getPackageName().equals(packageName)) {
   8452                 // Skip if component still exists in the package.
   8453                 if (componentsKnownToExist.contains(cn)) continue;
   8454 
   8455                 try {
   8456                     ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
   8457                     if (info != null) {
   8458                         componentsKnownToExist.add(cn);
   8459                     } else {
   8460                         removeTaskByIdLocked(tr.taskId, false);
   8461                     }
   8462                 } catch (RemoteException e) {
   8463                     Log.e(TAG, "Activity info query failed. component=" + cn, e);
   8464                 }
   8465             }
   8466         }
   8467     }
   8468 
   8469     /**
   8470      * Removes the task with the specified task id.
   8471      *
   8472      * @param taskId Identifier of the task to be removed.
   8473      * @param killProcess Kill any process associated with the task if possible.
   8474      * @return Returns true if the given task was found and removed.
   8475      */
   8476     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
   8477         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8478         if (tr != null) {
   8479             tr.removeTaskActivitiesLocked();
   8480             cleanUpRemovedTaskLocked(tr, killProcess);
   8481             if (tr.isPersistable) {
   8482                 notifyTaskPersisterLocked(null, true);
   8483             }
   8484             return true;
   8485         }
   8486         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
   8487         return false;
   8488     }
   8489 
   8490     @Override
   8491     public boolean removeTask(int taskId) {
   8492         synchronized (this) {
   8493             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   8494                     "removeTask()");
   8495             long ident = Binder.clearCallingIdentity();
   8496             try {
   8497                 return removeTaskByIdLocked(taskId, true);
   8498             } finally {
   8499                 Binder.restoreCallingIdentity(ident);
   8500             }
   8501         }
   8502     }
   8503 
   8504     /**
   8505      * TODO: Add mController hook
   8506      */
   8507     @Override
   8508     public void moveTaskToFront(int taskId, int flags, Bundle options) {
   8509         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8510                 "moveTaskToFront()");
   8511 
   8512         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
   8513         synchronized(this) {
   8514             moveTaskToFrontLocked(taskId, flags, options);
   8515         }
   8516     }
   8517 
   8518     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
   8519         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8520                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   8521             ActivityOptions.abort(options);
   8522             return;
   8523         }
   8524         final long origId = Binder.clearCallingIdentity();
   8525         try {
   8526             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8527             if (task == null) {
   8528                 Slog.d(TAG, "Could not find task for id: "+ taskId);
   8529                 return;
   8530             }
   8531             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   8532                 mStackSupervisor.showLockTaskToast();
   8533                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   8534                 return;
   8535             }
   8536             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   8537             if (prev != null && prev.isRecentsActivity()) {
   8538                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   8539             }
   8540             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
   8541         } finally {
   8542             Binder.restoreCallingIdentity(origId);
   8543         }
   8544         ActivityOptions.abort(options);
   8545     }
   8546 
   8547     @Override
   8548     public void moveTaskToBack(int taskId) {
   8549         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8550                 "moveTaskToBack()");
   8551 
   8552         synchronized(this) {
   8553             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8554             if (tr != null) {
   8555                 if (tr == mStackSupervisor.mLockTaskModeTask) {
   8556                     mStackSupervisor.showLockTaskToast();
   8557                     return;
   8558                 }
   8559                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
   8560                 ActivityStack stack = tr.stack;
   8561                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
   8562                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8563                             Binder.getCallingUid(), -1, -1, "Task to back")) {
   8564                         return;
   8565                     }
   8566                 }
   8567                 final long origId = Binder.clearCallingIdentity();
   8568                 try {
   8569                     stack.moveTaskToBackLocked(taskId);
   8570                 } finally {
   8571                     Binder.restoreCallingIdentity(origId);
   8572                 }
   8573             }
   8574         }
   8575     }
   8576 
   8577     /**
   8578      * Moves an activity, and all of the other activities within the same task, to the bottom
   8579      * of the history stack.  The activity's order within the task is unchanged.
   8580      *
   8581      * @param token A reference to the activity we wish to move
   8582      * @param nonRoot If false then this only works if the activity is the root
   8583      *                of a task; if true it will work for any activity in a task.
   8584      * @return Returns true if the move completed, false if not.
   8585      */
   8586     @Override
   8587     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   8588         enforceNotIsolatedCaller("moveActivityTaskToBack");
   8589         synchronized(this) {
   8590             final long origId = Binder.clearCallingIdentity();
   8591             try {
   8592                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   8593                 if (taskId >= 0) {
   8594                     if ((mStackSupervisor.mLockTaskModeTask != null)
   8595                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
   8596                         mStackSupervisor.showLockTaskToast();
   8597                         return false;
   8598                     }
   8599                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
   8600                 }
   8601             } finally {
   8602                 Binder.restoreCallingIdentity(origId);
   8603             }
   8604         }
   8605         return false;
   8606     }
   8607 
   8608     @Override
   8609     public void moveTaskBackwards(int task) {
   8610         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8611                 "moveTaskBackwards()");
   8612 
   8613         synchronized(this) {
   8614             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8615                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   8616                 return;
   8617             }
   8618             final long origId = Binder.clearCallingIdentity();
   8619             moveTaskBackwardsLocked(task);
   8620             Binder.restoreCallingIdentity(origId);
   8621         }
   8622     }
   8623 
   8624     private final void moveTaskBackwardsLocked(int task) {
   8625         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   8626     }
   8627 
   8628     @Override
   8629     public IBinder getHomeActivityToken() throws RemoteException {
   8630         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8631                 "getHomeActivityToken()");
   8632         synchronized (this) {
   8633             return mStackSupervisor.getHomeActivityToken();
   8634         }
   8635     }
   8636 
   8637     @Override
   8638     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
   8639             IActivityContainerCallback callback) throws RemoteException {
   8640         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8641                 "createActivityContainer()");
   8642         synchronized (this) {
   8643             if (parentActivityToken == null) {
   8644                 throw new IllegalArgumentException("parent token must not be null");
   8645             }
   8646             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
   8647             if (r == null) {
   8648                 return null;
   8649             }
   8650             if (callback == null) {
   8651                 throw new IllegalArgumentException("callback must not be null");
   8652             }
   8653             return mStackSupervisor.createActivityContainer(r, callback);
   8654         }
   8655     }
   8656 
   8657     @Override
   8658     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   8659         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8660                 "deleteActivityContainer()");
   8661         synchronized (this) {
   8662             mStackSupervisor.deleteActivityContainer(container);
   8663         }
   8664     }
   8665 
   8666     @Override
   8667     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
   8668         synchronized (this) {
   8669             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   8670             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
   8671                 return stack.mActivityContainer.getDisplayId();
   8672             }
   8673             return Display.DEFAULT_DISPLAY;
   8674         }
   8675     }
   8676 
   8677     @Override
   8678     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   8679         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8680                 "moveTaskToStack()");
   8681         if (stackId == HOME_STACK_ID) {
   8682             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
   8683                     new RuntimeException("here").fillInStackTrace());
   8684         }
   8685         synchronized (this) {
   8686             long ident = Binder.clearCallingIdentity();
   8687             try {
   8688                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
   8689                         + stackId + " toTop=" + toTop);
   8690                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
   8691             } finally {
   8692                 Binder.restoreCallingIdentity(ident);
   8693             }
   8694         }
   8695     }
   8696 
   8697     @Override
   8698     public void resizeStack(int stackBoxId, Rect bounds) {
   8699         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8700                 "resizeStackBox()");
   8701         long ident = Binder.clearCallingIdentity();
   8702         try {
   8703             mWindowManager.resizeStack(stackBoxId, bounds);
   8704         } finally {
   8705             Binder.restoreCallingIdentity(ident);
   8706         }
   8707     }
   8708 
   8709     @Override
   8710     public List<StackInfo> getAllStackInfos() {
   8711         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8712                 "getAllStackInfos()");
   8713         long ident = Binder.clearCallingIdentity();
   8714         try {
   8715             synchronized (this) {
   8716                 return mStackSupervisor.getAllStackInfosLocked();
   8717             }
   8718         } finally {
   8719             Binder.restoreCallingIdentity(ident);
   8720         }
   8721     }
   8722 
   8723     @Override
   8724     public StackInfo getStackInfo(int stackId) {
   8725         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8726                 "getStackInfo()");
   8727         long ident = Binder.clearCallingIdentity();
   8728         try {
   8729             synchronized (this) {
   8730                 return mStackSupervisor.getStackInfoLocked(stackId);
   8731             }
   8732         } finally {
   8733             Binder.restoreCallingIdentity(ident);
   8734         }
   8735     }
   8736 
   8737     @Override
   8738     public boolean isInHomeStack(int taskId) {
   8739         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8740                 "getStackInfo()");
   8741         long ident = Binder.clearCallingIdentity();
   8742         try {
   8743             synchronized (this) {
   8744                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
   8745                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   8746             }
   8747         } finally {
   8748             Binder.restoreCallingIdentity(ident);
   8749         }
   8750     }
   8751 
   8752     @Override
   8753     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   8754         synchronized(this) {
   8755             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   8756         }
   8757     }
   8758 
   8759     private boolean isLockTaskAuthorized(String pkg) {
   8760         final DevicePolicyManager dpm = (DevicePolicyManager)
   8761                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
   8762         try {
   8763             int uid = mContext.getPackageManager().getPackageUid(pkg,
   8764                     Binder.getCallingUserHandle().getIdentifier());
   8765             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
   8766         } catch (NameNotFoundException e) {
   8767             return false;
   8768         }
   8769     }
   8770 
   8771     void startLockTaskMode(TaskRecord task) {
   8772         final String pkg;
   8773         synchronized (this) {
   8774             pkg = task.intent.getComponent().getPackageName();
   8775         }
   8776         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
   8777         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
   8778             StatusBarManagerInternal statusBarManager = LocalServices.getService(
   8779                     StatusBarManagerInternal.class);
   8780             if (statusBarManager != null) {
   8781                 statusBarManager.showScreenPinningRequest();
   8782             }
   8783             return;
   8784         }
   8785         long ident = Binder.clearCallingIdentity();
   8786         try {
   8787             synchronized (this) {
   8788                 // Since we lost lock on task, make sure it is still there.
   8789                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
   8790                 if (task != null) {
   8791                     if (!isSystemInitiated
   8792                             && ((mStackSupervisor.getFocusedStack() == null)
   8793                                     || (task != mStackSupervisor.getFocusedStack().topTask()))) {
   8794                         throw new IllegalArgumentException("Invalid task, not in foreground");
   8795                     }
   8796                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
   8797                             "startLockTask");
   8798                 }
   8799             }
   8800         } finally {
   8801             Binder.restoreCallingIdentity(ident);
   8802         }
   8803     }
   8804 
   8805     @Override
   8806     public void startLockTaskMode(int taskId) {
   8807         final TaskRecord task;
   8808         long ident = Binder.clearCallingIdentity();
   8809         try {
   8810             synchronized (this) {
   8811                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8812             }
   8813         } finally {
   8814             Binder.restoreCallingIdentity(ident);
   8815         }
   8816         if (task != null) {
   8817             startLockTaskMode(task);
   8818         }
   8819     }
   8820 
   8821     @Override
   8822     public void startLockTaskMode(IBinder token) {
   8823         final TaskRecord task;
   8824         long ident = Binder.clearCallingIdentity();
   8825         try {
   8826             synchronized (this) {
   8827                 final ActivityRecord r = ActivityRecord.forToken(token);
   8828                 if (r == null) {
   8829                     return;
   8830                 }
   8831                 task = r.task;
   8832             }
   8833         } finally {
   8834             Binder.restoreCallingIdentity(ident);
   8835         }
   8836         if (task != null) {
   8837             startLockTaskMode(task);
   8838         }
   8839     }
   8840 
   8841     @Override
   8842     public void startLockTaskModeOnCurrent() throws RemoteException {
   8843         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8844                 "startLockTaskModeOnCurrent");
   8845         long ident = Binder.clearCallingIdentity();
   8846         try {
   8847             ActivityRecord r = null;
   8848             synchronized (this) {
   8849                 r = mStackSupervisor.topRunningActivityLocked();
   8850             }
   8851             startLockTaskMode(r.task);
   8852         } finally {
   8853             Binder.restoreCallingIdentity(ident);
   8854         }
   8855     }
   8856 
   8857     @Override
   8858     public void stopLockTaskMode() {
   8859         // Verify that the user matches the package of the intent for the TaskRecord
   8860         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
   8861         // and stopLockTaskMode.
   8862         final int callingUid = Binder.getCallingUid();
   8863         if (callingUid != Process.SYSTEM_UID) {
   8864             try {
   8865                 String pkg =
   8866                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
   8867                 int uid = mContext.getPackageManager().getPackageUid(pkg,
   8868                         Binder.getCallingUserHandle().getIdentifier());
   8869                 if (uid != callingUid) {
   8870                     throw new SecurityException("Invalid uid, expected " + uid);
   8871                 }
   8872             } catch (NameNotFoundException e) {
   8873                 Log.d(TAG, "stopLockTaskMode " + e);
   8874                 return;
   8875             }
   8876         }
   8877         long ident = Binder.clearCallingIdentity();
   8878         try {
   8879             Log.d(TAG, "stopLockTaskMode");
   8880             // Stop lock task
   8881             synchronized (this) {
   8882                 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
   8883             }
   8884         } finally {
   8885             Binder.restoreCallingIdentity(ident);
   8886         }
   8887     }
   8888 
   8889     @Override
   8890     public void stopLockTaskModeOnCurrent() throws RemoteException {
   8891         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8892                 "stopLockTaskModeOnCurrent");
   8893         long ident = Binder.clearCallingIdentity();
   8894         try {
   8895             stopLockTaskMode();
   8896         } finally {
   8897             Binder.restoreCallingIdentity(ident);
   8898         }
   8899     }
   8900 
   8901     @Override
   8902     public boolean isInLockTaskMode() {
   8903         synchronized (this) {
   8904             return mStackSupervisor.isInLockTaskMode();
   8905         }
   8906     }
   8907 
   8908     // =========================================================
   8909     // CONTENT PROVIDERS
   8910     // =========================================================
   8911 
   8912     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   8913         List<ProviderInfo> providers = null;
   8914         try {
   8915             providers = AppGlobals.getPackageManager().
   8916                 queryContentProviders(app.processName, app.uid,
   8917                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   8918         } catch (RemoteException ex) {
   8919         }
   8920         if (DEBUG_MU)
   8921             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   8922         int userId = app.userId;
   8923         if (providers != null) {
   8924             int N = providers.size();
   8925             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   8926             for (int i=0; i<N; i++) {
   8927                 ProviderInfo cpi =
   8928                     (ProviderInfo)providers.get(i);
   8929                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   8930                         cpi.name, cpi.flags);
   8931                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   8932                     // This is a singleton provider, but a user besides the
   8933                     // default user is asking to initialize a process it runs
   8934                     // in...  well, no, it doesn't actually run in this process,
   8935                     // it runs in the process of the default user.  Get rid of it.
   8936                     providers.remove(i);
   8937                     N--;
   8938                     i--;
   8939                     continue;
   8940                 }
   8941 
   8942                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   8943                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   8944                 if (cpr == null) {
   8945                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   8946                     mProviderMap.putProviderByClass(comp, cpr);
   8947                 }
   8948                 if (DEBUG_MU)
   8949                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   8950                 app.pubProviders.put(cpi.name, cpr);
   8951                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   8952                     // Don't add this if it is a platform component that is marked
   8953                     // to run in multiple processes, because this is actually
   8954                     // part of the framework so doesn't make sense to track as a
   8955                     // separate apk in the process.
   8956                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   8957                             mProcessStats);
   8958                 }
   8959                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   8960             }
   8961         }
   8962         return providers;
   8963     }
   8964 
   8965     /**
   8966      * Check if {@link ProcessRecord} has a possible chance at accessing the
   8967      * given {@link ProviderInfo}. Final permission checking is always done
   8968      * in {@link ContentProvider}.
   8969      */
   8970     private final String checkContentProviderPermissionLocked(
   8971             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   8972         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   8973         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   8974         boolean checkedGrants = false;
   8975         if (checkUser) {
   8976             // Looking for cross-user grants before enforcing the typical cross-users permissions
   8977             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
   8978             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   8979                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   8980                     return null;
   8981                 }
   8982                 checkedGrants = true;
   8983             }
   8984             userId = handleIncomingUser(callingPid, callingUid, userId,
   8985                     false, ALLOW_NON_FULL,
   8986                     "checkContentProviderPermissionLocked " + cpi.authority, null);
   8987             if (userId != tmpTargetUserId) {
   8988                 // When we actually went to determine the final targer user ID, this ended
   8989                 // up different than our initial check for the authority.  This is because
   8990                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   8991                 // SELF.  So we need to re-check the grants again.
   8992                 checkedGrants = false;
   8993             }
   8994         }
   8995         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   8996                 cpi.applicationInfo.uid, cpi.exported)
   8997                 == PackageManager.PERMISSION_GRANTED) {
   8998             return null;
   8999         }
   9000         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   9001                 cpi.applicationInfo.uid, cpi.exported)
   9002                 == PackageManager.PERMISSION_GRANTED) {
   9003             return null;
   9004         }
   9005 
   9006         PathPermission[] pps = cpi.pathPermissions;
   9007         if (pps != null) {
   9008             int i = pps.length;
   9009             while (i > 0) {
   9010                 i--;
   9011                 PathPermission pp = pps[i];
   9012                 String pprperm = pp.getReadPermission();
   9013                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   9014                         cpi.applicationInfo.uid, cpi.exported)
   9015                         == PackageManager.PERMISSION_GRANTED) {
   9016                     return null;
   9017                 }
   9018                 String ppwperm = pp.getWritePermission();
   9019                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   9020                         cpi.applicationInfo.uid, cpi.exported)
   9021                         == PackageManager.PERMISSION_GRANTED) {
   9022                     return null;
   9023                 }
   9024             }
   9025         }
   9026         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   9027             return null;
   9028         }
   9029 
   9030         String msg;
   9031         if (!cpi.exported) {
   9032             msg = "Permission Denial: opening provider " + cpi.name
   9033                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9034                     + ", uid=" + callingUid + ") that is not exported from uid "
   9035                     + cpi.applicationInfo.uid;
   9036         } else {
   9037             msg = "Permission Denial: opening provider " + cpi.name
   9038                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9039                     + ", uid=" + callingUid + ") requires "
   9040                     + cpi.readPermission + " or " + cpi.writePermission;
   9041         }
   9042         Slog.w(TAG, msg);
   9043         return msg;
   9044     }
   9045 
   9046     /**
   9047      * Returns if the ContentProvider has granted a uri to callingUid
   9048      */
   9049     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   9050         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   9051         if (perms != null) {
   9052             for (int i=perms.size()-1; i>=0; i--) {
   9053                 GrantUri grantUri = perms.keyAt(i);
   9054                 if (grantUri.sourceUserId == userId || !checkUser) {
   9055                     if (matchesProvider(grantUri.uri, cpi)) {
   9056                         return true;
   9057                     }
   9058                 }
   9059             }
   9060         }
   9061         return false;
   9062     }
   9063 
   9064     /**
   9065      * Returns true if the uri authority is one of the authorities specified in the provider.
   9066      */
   9067     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   9068         String uriAuth = uri.getAuthority();
   9069         String cpiAuth = cpi.authority;
   9070         if (cpiAuth.indexOf(';') == -1) {
   9071             return cpiAuth.equals(uriAuth);
   9072         }
   9073         String[] cpiAuths = cpiAuth.split(";");
   9074         int length = cpiAuths.length;
   9075         for (int i = 0; i < length; i++) {
   9076             if (cpiAuths[i].equals(uriAuth)) return true;
   9077         }
   9078         return false;
   9079     }
   9080 
   9081     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   9082             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9083         if (r != null) {
   9084             for (int i=0; i<r.conProviders.size(); i++) {
   9085                 ContentProviderConnection conn = r.conProviders.get(i);
   9086                 if (conn.provider == cpr) {
   9087                     if (DEBUG_PROVIDER) Slog.v(TAG,
   9088                             "Adding provider requested by "
   9089                             + r.processName + " from process "
   9090                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9091                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9092                     if (stable) {
   9093                         conn.stableCount++;
   9094                         conn.numStableIncs++;
   9095                     } else {
   9096                         conn.unstableCount++;
   9097                         conn.numUnstableIncs++;
   9098                     }
   9099                     return conn;
   9100                 }
   9101             }
   9102             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   9103             if (stable) {
   9104                 conn.stableCount = 1;
   9105                 conn.numStableIncs = 1;
   9106             } else {
   9107                 conn.unstableCount = 1;
   9108                 conn.numUnstableIncs = 1;
   9109             }
   9110             cpr.connections.add(conn);
   9111             r.conProviders.add(conn);
   9112             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
   9113             return conn;
   9114         }
   9115         cpr.addExternalProcessHandleLocked(externalProcessToken);
   9116         return null;
   9117     }
   9118 
   9119     boolean decProviderCountLocked(ContentProviderConnection conn,
   9120             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9121         if (conn != null) {
   9122             cpr = conn.provider;
   9123             if (DEBUG_PROVIDER) Slog.v(TAG,
   9124                     "Removing provider requested by "
   9125                     + conn.client.processName + " from process "
   9126                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9127                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9128             if (stable) {
   9129                 conn.stableCount--;
   9130             } else {
   9131                 conn.unstableCount--;
   9132             }
   9133             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   9134                 cpr.connections.remove(conn);
   9135                 conn.client.conProviders.remove(conn);
   9136                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
   9137                 return true;
   9138             }
   9139             return false;
   9140         }
   9141         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   9142         return false;
   9143     }
   9144 
   9145     private void checkTime(long startTime, String where) {
   9146         long now = SystemClock.elapsedRealtime();
   9147         if ((now-startTime) > 1000) {
   9148             // If we are taking more than a second, log about it.
   9149             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   9150         }
   9151     }
   9152 
   9153     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   9154             String name, IBinder token, boolean stable, int userId) {
   9155         ContentProviderRecord cpr;
   9156         ContentProviderConnection conn = null;
   9157         ProviderInfo cpi = null;
   9158 
   9159         synchronized(this) {
   9160             long startTime = SystemClock.elapsedRealtime();
   9161 
   9162             ProcessRecord r = null;
   9163             if (caller != null) {
   9164                 r = getRecordForAppLocked(caller);
   9165                 if (r == null) {
   9166                     throw new SecurityException(
   9167                             "Unable to find app for caller " + caller
   9168                           + " (pid=" + Binder.getCallingPid()
   9169                           + ") when getting content provider " + name);
   9170                 }
   9171             }
   9172 
   9173             boolean checkCrossUser = true;
   9174 
   9175             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   9176 
   9177             // First check if this content provider has been published...
   9178             cpr = mProviderMap.getProviderByName(name, userId);
   9179             // If that didn't work, check if it exists for user 0 and then
   9180             // verify that it's a singleton provider before using it.
   9181             if (cpr == null && userId != UserHandle.USER_OWNER) {
   9182                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
   9183                 if (cpr != null) {
   9184                     cpi = cpr.info;
   9185                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   9186                             cpi.name, cpi.flags)
   9187                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   9188                         userId = UserHandle.USER_OWNER;
   9189                         checkCrossUser = false;
   9190                     } else {
   9191                         cpr = null;
   9192                         cpi = null;
   9193                     }
   9194                 }
   9195             }
   9196 
   9197             boolean providerRunning = cpr != null;
   9198             if (providerRunning) {
   9199                 cpi = cpr.info;
   9200                 String msg;
   9201                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9202                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   9203                         != null) {
   9204                     throw new SecurityException(msg);
   9205                 }
   9206                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9207 
   9208                 if (r != null && cpr.canRunHere(r)) {
   9209                     // This provider has been published or is in the process
   9210                     // of being published...  but it is also allowed to run
   9211                     // in the caller's process, so don't make a connection
   9212                     // and just let the caller instantiate its own instance.
   9213                     ContentProviderHolder holder = cpr.newHolder(null);
   9214                     // don't give caller the provider object, it needs
   9215                     // to make its own.
   9216                     holder.provider = null;
   9217                     return holder;
   9218                 }
   9219 
   9220                 final long origId = Binder.clearCallingIdentity();
   9221 
   9222                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   9223 
   9224                 // In this case the provider instance already exists, so we can
   9225                 // return it right away.
   9226                 conn = incProviderCountLocked(r, cpr, token, stable);
   9227                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   9228                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9229                         // If this is a perceptible app accessing the provider,
   9230                         // make sure to count it as being accessed and thus
   9231                         // back up on the LRU list.  This is good because
   9232                         // content providers are often expensive to start.
   9233                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   9234                         updateLruProcessLocked(cpr.proc, false, null);
   9235                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   9236                     }
   9237                 }
   9238 
   9239                 if (cpr.proc != null) {
   9240                     if (false) {
   9241                         if (cpr.name.flattenToShortString().equals(
   9242                                 "com.android.providers.calendar/.CalendarProvider2")) {
   9243                             Slog.v(TAG, "****************** KILLING "
   9244                                 + cpr.name.flattenToShortString());
   9245                             Process.killProcess(cpr.proc.pid);
   9246                         }
   9247                     }
   9248                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   9249                     boolean success = updateOomAdjLocked(cpr.proc);
   9250                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   9251                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   9252                     // NOTE: there is still a race here where a signal could be
   9253                     // pending on the process even though we managed to update its
   9254                     // adj level.  Not sure what to do about this, but at least
   9255                     // the race is now smaller.
   9256                     if (!success) {
   9257                         // Uh oh...  it looks like the provider's process
   9258                         // has been killed on us.  We need to wait for a new
   9259                         // process to be started, and make sure its death
   9260                         // doesn't kill our process.
   9261                         Slog.i(TAG,
   9262                                 "Existing provider " + cpr.name.flattenToShortString()
   9263                                 + " is crashing; detaching " + r);
   9264                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   9265                         checkTime(startTime, "getContentProviderImpl: before appDied");
   9266                         appDiedLocked(cpr.proc);
   9267                         checkTime(startTime, "getContentProviderImpl: after appDied");
   9268                         if (!lastRef) {
   9269                             // This wasn't the last ref our process had on
   9270                             // the provider...  we have now been killed, bail.
   9271                             return null;
   9272                         }
   9273                         providerRunning = false;
   9274                         conn = null;
   9275                     }
   9276                 }
   9277 
   9278                 Binder.restoreCallingIdentity(origId);
   9279             }
   9280 
   9281             boolean singleton;
   9282             if (!providerRunning) {
   9283                 try {
   9284                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   9285                     cpi = AppGlobals.getPackageManager().
   9286                         resolveContentProvider(name,
   9287                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   9288                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   9289                 } catch (RemoteException ex) {
   9290                 }
   9291                 if (cpi == null) {
   9292                     return null;
   9293                 }
   9294                 // If the provider is a singleton AND
   9295                 // (it's a call within the same user || the provider is a
   9296                 // privileged app)
   9297                 // Then allow connecting to the singleton provider
   9298                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   9299                         cpi.name, cpi.flags)
   9300                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   9301                 if (singleton) {
   9302                     userId = UserHandle.USER_OWNER;
   9303                 }
   9304                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   9305                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   9306 
   9307                 String msg;
   9308                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9309                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   9310                         != null) {
   9311                     throw new SecurityException(msg);
   9312                 }
   9313                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9314 
   9315                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   9316                         && !cpi.processName.equals("system")) {
   9317                     // If this content provider does not run in the system
   9318                     // process, and the system is not yet ready to run other
   9319                     // processes, then fail fast instead of hanging.
   9320                     throw new IllegalArgumentException(
   9321                             "Attempt to launch content provider before system ready");
   9322                 }
   9323 
   9324                 // Make sure that the user who owns this provider is running.  If not,
   9325                 // we don't want to allow it to run.
   9326                 if (!isUserRunningLocked(userId, false)) {
   9327                     Slog.w(TAG, "Unable to launch app "
   9328                             + cpi.applicationInfo.packageName + "/"
   9329                             + cpi.applicationInfo.uid + " for provider "
   9330                             + name + ": user " + userId + " is stopped");
   9331                     return null;
   9332                 }
   9333 
   9334                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   9335                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   9336                 cpr = mProviderMap.getProviderByClass(comp, userId);
   9337                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   9338                 final boolean firstClass = cpr == null;
   9339                 if (firstClass) {
   9340                     final long ident = Binder.clearCallingIdentity();
   9341                     try {
   9342                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   9343                         ApplicationInfo ai =
   9344                             AppGlobals.getPackageManager().
   9345                                 getApplicationInfo(
   9346                                         cpi.applicationInfo.packageName,
   9347                                         STOCK_PM_FLAGS, userId);
   9348                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   9349                         if (ai == null) {
   9350                             Slog.w(TAG, "No package info for content provider "
   9351                                     + cpi.name);
   9352                             return null;
   9353                         }
   9354                         ai = getAppInfoForUser(ai, userId);
   9355                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   9356                     } catch (RemoteException ex) {
   9357                         // pm is in same process, this will never happen.
   9358                     } finally {
   9359                         Binder.restoreCallingIdentity(ident);
   9360                     }
   9361                 }
   9362 
   9363                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   9364 
   9365                 if (r != null && cpr.canRunHere(r)) {
   9366                     // If this is a multiprocess provider, then just return its
   9367                     // info and allow the caller to instantiate it.  Only do
   9368                     // this if the provider is the same user as the caller's
   9369                     // process, or can run as root (so can be in any process).
   9370                     return cpr.newHolder(null);
   9371                 }
   9372 
   9373                 if (DEBUG_PROVIDER) {
   9374                     RuntimeException e = new RuntimeException("here");
   9375                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
   9376                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   9377                 }
   9378 
   9379                 // This is single process, and our app is now connecting to it.
   9380                 // See if we are already in the process of launching this
   9381                 // provider.
   9382                 final int N = mLaunchingProviders.size();
   9383                 int i;
   9384                 for (i=0; i<N; i++) {
   9385                     if (mLaunchingProviders.get(i) == cpr) {
   9386                         break;
   9387                     }
   9388                 }
   9389 
   9390                 // If the provider is not already being launched, then get it
   9391                 // started.
   9392                 if (i >= N) {
   9393                     final long origId = Binder.clearCallingIdentity();
   9394 
   9395                     try {
   9396                         // Content provider is now in use, its package can't be stopped.
   9397                         try {
   9398                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   9399                             AppGlobals.getPackageManager().setPackageStoppedState(
   9400                                     cpr.appInfo.packageName, false, userId);
   9401                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   9402                         } catch (RemoteException e) {
   9403                         } catch (IllegalArgumentException e) {
   9404                             Slog.w(TAG, "Failed trying to unstop package "
   9405                                     + cpr.appInfo.packageName + ": " + e);
   9406                         }
   9407 
   9408                         // Use existing process if already started
   9409                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   9410                         ProcessRecord proc = getProcessRecordLocked(
   9411                                 cpi.processName, cpr.appInfo.uid, false);
   9412                         if (proc != null && proc.thread != null) {
   9413                             if (DEBUG_PROVIDER) {
   9414                                 Slog.d(TAG, "Installing in existing process " + proc);
   9415                             }
   9416                             checkTime(startTime, "getContentProviderImpl: scheduling install");
   9417                             proc.pubProviders.put(cpi.name, cpr);
   9418                             try {
   9419                                 proc.thread.scheduleInstallProvider(cpi);
   9420                             } catch (RemoteException e) {
   9421                             }
   9422                         } else {
   9423                             checkTime(startTime, "getContentProviderImpl: before start process");
   9424                             proc = startProcessLocked(cpi.processName,
   9425                                     cpr.appInfo, false, 0, "content provider",
   9426                                     new ComponentName(cpi.applicationInfo.packageName,
   9427                                             cpi.name), false, false, false);
   9428                             checkTime(startTime, "getContentProviderImpl: after start process");
   9429                             if (proc == null) {
   9430                                 Slog.w(TAG, "Unable to launch app "
   9431                                         + cpi.applicationInfo.packageName + "/"
   9432                                         + cpi.applicationInfo.uid + " for provider "
   9433                                         + name + ": process is bad");
   9434                                 return null;
   9435                             }
   9436                         }
   9437                         cpr.launchingApp = proc;
   9438                         mLaunchingProviders.add(cpr);
   9439                     } finally {
   9440                         Binder.restoreCallingIdentity(origId);
   9441                     }
   9442                 }
   9443 
   9444                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   9445 
   9446                 // Make sure the provider is published (the same provider class
   9447                 // may be published under multiple names).
   9448                 if (firstClass) {
   9449                     mProviderMap.putProviderByClass(comp, cpr);
   9450                 }
   9451 
   9452                 mProviderMap.putProviderByName(name, cpr);
   9453                 conn = incProviderCountLocked(r, cpr, token, stable);
   9454                 if (conn != null) {
   9455                     conn.waiting = true;
   9456                 }
   9457             }
   9458             checkTime(startTime, "getContentProviderImpl: done!");
   9459         }
   9460 
   9461         // Wait for the provider to be published...
   9462         synchronized (cpr) {
   9463             while (cpr.provider == null) {
   9464                 if (cpr.launchingApp == null) {
   9465                     Slog.w(TAG, "Unable to launch app "
   9466                             + cpi.applicationInfo.packageName + "/"
   9467                             + cpi.applicationInfo.uid + " for provider "
   9468                             + name + ": launching app became null");
   9469                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   9470                             UserHandle.getUserId(cpi.applicationInfo.uid),
   9471                             cpi.applicationInfo.packageName,
   9472                             cpi.applicationInfo.uid, name);
   9473                     return null;
   9474                 }
   9475                 try {
   9476                     if (DEBUG_MU) {
   9477                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   9478                                 + cpr.launchingApp);
   9479                     }
   9480                     if (conn != null) {
   9481                         conn.waiting = true;
   9482                     }
   9483                     cpr.wait();
   9484                 } catch (InterruptedException ex) {
   9485                 } finally {
   9486                     if (conn != null) {
   9487                         conn.waiting = false;
   9488                     }
   9489                 }
   9490             }
   9491         }
   9492         return cpr != null ? cpr.newHolder(conn) : null;
   9493     }
   9494 
   9495     @Override
   9496     public final ContentProviderHolder getContentProvider(
   9497             IApplicationThread caller, String name, int userId, boolean stable) {
   9498         enforceNotIsolatedCaller("getContentProvider");
   9499         if (caller == null) {
   9500             String msg = "null IApplicationThread when getting content provider "
   9501                     + name;
   9502             Slog.w(TAG, msg);
   9503             throw new SecurityException(msg);
   9504         }
   9505         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   9506         // with cross-user grant.
   9507         return getContentProviderImpl(caller, name, null, stable, userId);
   9508     }
   9509 
   9510     public ContentProviderHolder getContentProviderExternal(
   9511             String name, int userId, IBinder token) {
   9512         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9513             "Do not have permission in call getContentProviderExternal()");
   9514         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   9515                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
   9516         return getContentProviderExternalUnchecked(name, token, userId);
   9517     }
   9518 
   9519     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   9520             IBinder token, int userId) {
   9521         return getContentProviderImpl(null, name, token, true, userId);
   9522     }
   9523 
   9524     /**
   9525      * Drop a content provider from a ProcessRecord's bookkeeping
   9526      */
   9527     public void removeContentProvider(IBinder connection, boolean stable) {
   9528         enforceNotIsolatedCaller("removeContentProvider");
   9529         long ident = Binder.clearCallingIdentity();
   9530         try {
   9531             synchronized (this) {
   9532                 ContentProviderConnection conn;
   9533                 try {
   9534                     conn = (ContentProviderConnection)connection;
   9535                 } catch (ClassCastException e) {
   9536                     String msg ="removeContentProvider: " + connection
   9537                             + " not a ContentProviderConnection";
   9538                     Slog.w(TAG, msg);
   9539                     throw new IllegalArgumentException(msg);
   9540                 }
   9541                 if (conn == null) {
   9542                     throw new NullPointerException("connection is null");
   9543                 }
   9544                 if (decProviderCountLocked(conn, null, null, stable)) {
   9545                     updateOomAdjLocked();
   9546                 }
   9547             }
   9548         } finally {
   9549             Binder.restoreCallingIdentity(ident);
   9550         }
   9551     }
   9552 
   9553     public void removeContentProviderExternal(String name, IBinder token) {
   9554         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9555             "Do not have permission in call removeContentProviderExternal()");
   9556         int userId = UserHandle.getCallingUserId();
   9557         long ident = Binder.clearCallingIdentity();
   9558         try {
   9559             removeContentProviderExternalUnchecked(name, token, userId);
   9560         } finally {
   9561             Binder.restoreCallingIdentity(ident);
   9562         }
   9563     }
   9564 
   9565     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   9566         synchronized (this) {
   9567             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   9568             if(cpr == null) {
   9569                 //remove from mProvidersByClass
   9570                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   9571                 return;
   9572             }
   9573 
   9574             //update content provider record entry info
   9575             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   9576             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   9577             if (localCpr.hasExternalProcessHandles()) {
   9578                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   9579                     updateOomAdjLocked();
   9580                 } else {
   9581                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   9582                             + " with no external reference for token: "
   9583                             + token + ".");
   9584                 }
   9585             } else {
   9586                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   9587                         + " with no external references.");
   9588             }
   9589         }
   9590     }
   9591 
   9592     public final void publishContentProviders(IApplicationThread caller,
   9593             List<ContentProviderHolder> providers) {
   9594         if (providers == null) {
   9595             return;
   9596         }
   9597 
   9598         enforceNotIsolatedCaller("publishContentProviders");
   9599         synchronized (this) {
   9600             final ProcessRecord r = getRecordForAppLocked(caller);
   9601             if (DEBUG_MU)
   9602                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   9603             if (r == null) {
   9604                 throw new SecurityException(
   9605                         "Unable to find app for caller " + caller
   9606                       + " (pid=" + Binder.getCallingPid()
   9607                       + ") when publishing content providers");
   9608             }
   9609 
   9610             final long origId = Binder.clearCallingIdentity();
   9611 
   9612             final int N = providers.size();
   9613             for (int i=0; i<N; i++) {
   9614                 ContentProviderHolder src = providers.get(i);
   9615                 if (src == null || src.info == null || src.provider == null) {
   9616                     continue;
   9617                 }
   9618                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   9619                 if (DEBUG_MU)
   9620                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   9621                 if (dst != null) {
   9622                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   9623                     mProviderMap.putProviderByClass(comp, dst);
   9624                     String names[] = dst.info.authority.split(";");
   9625                     for (int j = 0; j < names.length; j++) {
   9626                         mProviderMap.putProviderByName(names[j], dst);
   9627                     }
   9628 
   9629                     int NL = mLaunchingProviders.size();
   9630                     int j;
   9631                     for (j=0; j<NL; j++) {
   9632                         if (mLaunchingProviders.get(j) == dst) {
   9633                             mLaunchingProviders.remove(j);
   9634                             j--;
   9635                             NL--;
   9636                         }
   9637                     }
   9638                     synchronized (dst) {
   9639                         dst.provider = src.provider;
   9640                         dst.proc = r;
   9641                         dst.notifyAll();
   9642                     }
   9643                     updateOomAdjLocked(r);
   9644                 }
   9645             }
   9646 
   9647             Binder.restoreCallingIdentity(origId);
   9648         }
   9649     }
   9650 
   9651     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   9652         ContentProviderConnection conn;
   9653         try {
   9654             conn = (ContentProviderConnection)connection;
   9655         } catch (ClassCastException e) {
   9656             String msg ="refContentProvider: " + connection
   9657                     + " not a ContentProviderConnection";
   9658             Slog.w(TAG, msg);
   9659             throw new IllegalArgumentException(msg);
   9660         }
   9661         if (conn == null) {
   9662             throw new NullPointerException("connection is null");
   9663         }
   9664 
   9665         synchronized (this) {
   9666             if (stable > 0) {
   9667                 conn.numStableIncs += stable;
   9668             }
   9669             stable = conn.stableCount + stable;
   9670             if (stable < 0) {
   9671                 throw new IllegalStateException("stableCount < 0: " + stable);
   9672             }
   9673 
   9674             if (unstable > 0) {
   9675                 conn.numUnstableIncs += unstable;
   9676             }
   9677             unstable = conn.unstableCount + unstable;
   9678             if (unstable < 0) {
   9679                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   9680             }
   9681 
   9682             if ((stable+unstable) <= 0) {
   9683                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   9684                         + stable + " unstable=" + unstable);
   9685             }
   9686             conn.stableCount = stable;
   9687             conn.unstableCount = unstable;
   9688             return !conn.dead;
   9689         }
   9690     }
   9691 
   9692     public void unstableProviderDied(IBinder connection) {
   9693         ContentProviderConnection conn;
   9694         try {
   9695             conn = (ContentProviderConnection)connection;
   9696         } catch (ClassCastException e) {
   9697             String msg ="refContentProvider: " + connection
   9698                     + " not a ContentProviderConnection";
   9699             Slog.w(TAG, msg);
   9700             throw new IllegalArgumentException(msg);
   9701         }
   9702         if (conn == null) {
   9703             throw new NullPointerException("connection is null");
   9704         }
   9705 
   9706         // Safely retrieve the content provider associated with the connection.
   9707         IContentProvider provider;
   9708         synchronized (this) {
   9709             provider = conn.provider.provider;
   9710         }
   9711 
   9712         if (provider == null) {
   9713             // Um, yeah, we're way ahead of you.
   9714             return;
   9715         }
   9716 
   9717         // Make sure the caller is being honest with us.
   9718         if (provider.asBinder().pingBinder()) {
   9719             // Er, no, still looks good to us.
   9720             synchronized (this) {
   9721                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   9722                         + " says " + conn + " died, but we don't agree");
   9723                 return;
   9724             }
   9725         }
   9726 
   9727         // Well look at that!  It's dead!
   9728         synchronized (this) {
   9729             if (conn.provider.provider != provider) {
   9730                 // But something changed...  good enough.
   9731                 return;
   9732             }
   9733 
   9734             ProcessRecord proc = conn.provider.proc;
   9735             if (proc == null || proc.thread == null) {
   9736                 // Seems like the process is already cleaned up.
   9737                 return;
   9738             }
   9739 
   9740             // As far as we're concerned, this is just like receiving a
   9741             // death notification...  just a bit prematurely.
   9742             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   9743                     + ") early provider death");
   9744             final long ident = Binder.clearCallingIdentity();
   9745             try {
   9746                 appDiedLocked(proc);
   9747             } finally {
   9748                 Binder.restoreCallingIdentity(ident);
   9749             }
   9750         }
   9751     }
   9752 
   9753     @Override
   9754     public void appNotRespondingViaProvider(IBinder connection) {
   9755         enforceCallingPermission(
   9756                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   9757 
   9758         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   9759         if (conn == null) {
   9760             Slog.w(TAG, "ContentProviderConnection is null");
   9761             return;
   9762         }
   9763 
   9764         final ProcessRecord host = conn.provider.proc;
   9765         if (host == null) {
   9766             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   9767             return;
   9768         }
   9769 
   9770         final long token = Binder.clearCallingIdentity();
   9771         try {
   9772             appNotResponding(host, null, null, false, "ContentProvider not responding");
   9773         } finally {
   9774             Binder.restoreCallingIdentity(token);
   9775         }
   9776     }
   9777 
   9778     public final void installSystemProviders() {
   9779         List<ProviderInfo> providers;
   9780         synchronized (this) {
   9781             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   9782             providers = generateApplicationProvidersLocked(app);
   9783             if (providers != null) {
   9784                 for (int i=providers.size()-1; i>=0; i--) {
   9785                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   9786                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   9787                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   9788                                 + ": not system .apk");
   9789                         providers.remove(i);
   9790                     }
   9791                 }
   9792             }
   9793         }
   9794         if (providers != null) {
   9795             mSystemThread.installSystemProviders(providers);
   9796         }
   9797 
   9798         mCoreSettingsObserver = new CoreSettingsObserver(this);
   9799 
   9800         //mUsageStatsService.monitorPackages();
   9801     }
   9802 
   9803     /**
   9804      * Allows apps to retrieve the MIME type of a URI.
   9805      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   9806      * users, then it does not need permission to access the ContentProvider.
   9807      * Either, it needs cross-user uri grants.
   9808      *
   9809      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   9810      *
   9811      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   9812      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   9813      */
   9814     public String getProviderMimeType(Uri uri, int userId) {
   9815         enforceNotIsolatedCaller("getProviderMimeType");
   9816         final String name = uri.getAuthority();
   9817         int callingUid = Binder.getCallingUid();
   9818         int callingPid = Binder.getCallingPid();
   9819         long ident = 0;
   9820         boolean clearedIdentity = false;
   9821         userId = unsafeConvertIncomingUser(userId);
   9822         if (canClearIdentity(callingPid, callingUid, userId)) {
   9823             clearedIdentity = true;
   9824             ident = Binder.clearCallingIdentity();
   9825         }
   9826         ContentProviderHolder holder = null;
   9827         try {
   9828             holder = getContentProviderExternalUnchecked(name, null, userId);
   9829             if (holder != null) {
   9830                 return holder.provider.getType(uri);
   9831             }
   9832         } catch (RemoteException e) {
   9833             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   9834             return null;
   9835         } finally {
   9836             // We need to clear the identity to call removeContentProviderExternalUnchecked
   9837             if (!clearedIdentity) {
   9838                 ident = Binder.clearCallingIdentity();
   9839             }
   9840             try {
   9841                 if (holder != null) {
   9842                     removeContentProviderExternalUnchecked(name, null, userId);
   9843                 }
   9844             } finally {
   9845                 Binder.restoreCallingIdentity(ident);
   9846             }
   9847         }
   9848 
   9849         return null;
   9850     }
   9851 
   9852     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   9853         if (UserHandle.getUserId(callingUid) == userId) {
   9854             return true;
   9855         }
   9856         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   9857                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   9858                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   9859                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   9860                 return true;
   9861         }
   9862         return false;
   9863     }
   9864 
   9865     // =========================================================
   9866     // GLOBAL MANAGEMENT
   9867     // =========================================================
   9868 
   9869     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   9870             boolean isolated, int isolatedUid) {
   9871         String proc = customProcess != null ? customProcess : info.processName;
   9872         BatteryStatsImpl.Uid.Proc ps = null;
   9873         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9874         int uid = info.uid;
   9875         if (isolated) {
   9876             if (isolatedUid == 0) {
   9877                 int userId = UserHandle.getUserId(uid);
   9878                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   9879                 while (true) {
   9880                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   9881                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   9882                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   9883                     }
   9884                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   9885                     mNextIsolatedProcessUid++;
   9886                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   9887                         // No process for this uid, use it.
   9888                         break;
   9889                     }
   9890                     stepsLeft--;
   9891                     if (stepsLeft <= 0) {
   9892                         return null;
   9893                     }
   9894                 }
   9895             } else {
   9896                 // Special case for startIsolatedProcess (internal only), where
   9897                 // the uid of the isolated process is specified by the caller.
   9898                 uid = isolatedUid;
   9899             }
   9900         }
   9901         return new ProcessRecord(stats, info, proc, uid);
   9902     }
   9903 
   9904     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   9905             String abiOverride) {
   9906         ProcessRecord app;
   9907         if (!isolated) {
   9908             app = getProcessRecordLocked(info.processName, info.uid, true);
   9909         } else {
   9910             app = null;
   9911         }
   9912 
   9913         if (app == null) {
   9914             app = newProcessRecordLocked(info, null, isolated, 0);
   9915             mProcessNames.put(info.processName, app.uid, app);
   9916             if (isolated) {
   9917                 mIsolatedProcesses.put(app.uid, app);
   9918             }
   9919             updateLruProcessLocked(app, false, null);
   9920             updateOomAdjLocked();
   9921         }
   9922 
   9923         // This package really, really can not be stopped.
   9924         try {
   9925             AppGlobals.getPackageManager().setPackageStoppedState(
   9926                     info.packageName, false, UserHandle.getUserId(app.uid));
   9927         } catch (RemoteException e) {
   9928         } catch (IllegalArgumentException e) {
   9929             Slog.w(TAG, "Failed trying to unstop package "
   9930                     + info.packageName + ": " + e);
   9931         }
   9932 
   9933         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   9934                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   9935             app.persistent = true;
   9936             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   9937         }
   9938         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   9939             mPersistentStartingProcesses.add(app);
   9940             startProcessLocked(app, "added application", app.processName, abiOverride,
   9941                     null /* entryPoint */, null /* entryPointArgs */);
   9942         }
   9943 
   9944         return app;
   9945     }
   9946 
   9947     public void unhandledBack() {
   9948         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   9949                 "unhandledBack()");
   9950 
   9951         synchronized(this) {
   9952             final long origId = Binder.clearCallingIdentity();
   9953             try {
   9954                 getFocusedStack().unhandledBackLocked();
   9955             } finally {
   9956                 Binder.restoreCallingIdentity(origId);
   9957             }
   9958         }
   9959     }
   9960 
   9961     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   9962         enforceNotIsolatedCaller("openContentUri");
   9963         final int userId = UserHandle.getCallingUserId();
   9964         String name = uri.getAuthority();
   9965         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   9966         ParcelFileDescriptor pfd = null;
   9967         if (cph != null) {
   9968             // We record the binder invoker's uid in thread-local storage before
   9969             // going to the content provider to open the file.  Later, in the code
   9970             // that handles all permissions checks, we look for this uid and use
   9971             // that rather than the Activity Manager's own uid.  The effect is that
   9972             // we do the check against the caller's permissions even though it looks
   9973             // to the content provider like the Activity Manager itself is making
   9974             // the request.
   9975             Binder token = new Binder();
   9976             sCallerIdentity.set(new Identity(
   9977                     token, Binder.getCallingPid(), Binder.getCallingUid()));
   9978             try {
   9979                 pfd = cph.provider.openFile(null, uri, "r", null, token);
   9980             } catch (FileNotFoundException e) {
   9981                 // do nothing; pfd will be returned null
   9982             } finally {
   9983                 // Ensure that whatever happens, we clean up the identity state
   9984                 sCallerIdentity.remove();
   9985             }
   9986 
   9987             // We've got the fd now, so we're done with the provider.
   9988             removeContentProviderExternalUnchecked(name, null, userId);
   9989         } else {
   9990             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   9991         }
   9992         return pfd;
   9993     }
   9994 
   9995     // Actually is sleeping or shutting down or whatever else in the future
   9996     // is an inactive state.
   9997     public boolean isSleepingOrShuttingDown() {
   9998         return isSleeping() || mShuttingDown;
   9999     }
   10000 
   10001     public boolean isSleeping() {
   10002         return mSleeping;
   10003     }
   10004 
   10005     void onWakefulnessChanged(int wakefulness) {
   10006         synchronized(this) {
   10007             mWakefulness = wakefulness;
   10008             updateSleepIfNeededLocked();
   10009         }
   10010     }
   10011 
   10012     void finishRunningVoiceLocked() {
   10013         if (mRunningVoice) {
   10014             mRunningVoice = false;
   10015             updateSleepIfNeededLocked();
   10016         }
   10017     }
   10018 
   10019     void updateSleepIfNeededLocked() {
   10020         if (mSleeping && !shouldSleepLocked()) {
   10021             mSleeping = false;
   10022             mStackSupervisor.comeOutOfSleepIfNeededLocked();
   10023         } else if (!mSleeping && shouldSleepLocked()) {
   10024             mSleeping = true;
   10025             mStackSupervisor.goingToSleepLocked();
   10026 
   10027             // Initialize the wake times of all processes.
   10028             checkExcessivePowerUsageLocked(false);
   10029             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10030             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10031             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   10032         }
   10033     }
   10034 
   10035     private boolean shouldSleepLocked() {
   10036         // Resume applications while running a voice interactor.
   10037         if (mRunningVoice) {
   10038             return false;
   10039         }
   10040 
   10041         switch (mWakefulness) {
   10042             case PowerManagerInternal.WAKEFULNESS_AWAKE:
   10043             case PowerManagerInternal.WAKEFULNESS_DREAMING:
   10044                 // If we're interactive but applications are already paused then defer
   10045                 // resuming them until the lock screen is hidden.
   10046                 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
   10047             case PowerManagerInternal.WAKEFULNESS_DOZING:
   10048                 // If we're dozing then pause applications whenever the lock screen is shown.
   10049                 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
   10050             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
   10051             default:
   10052                 // If we're asleep then pause applications unconditionally.
   10053                 return true;
   10054         }
   10055     }
   10056 
   10057     /** Pokes the task persister. */
   10058     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   10059         if (task != null && task.stack != null && task.stack.isHomeStack()) {
   10060             // Never persist the home stack.
   10061             return;
   10062         }
   10063         mTaskPersister.wakeup(task, flush);
   10064     }
   10065 
   10066     /** Notifies all listeners when the task stack has changed. */
   10067     void notifyTaskStackChangedLocked() {
   10068         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   10069         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
   10070         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
   10071     }
   10072 
   10073     @Override
   10074     public boolean shutdown(int timeout) {
   10075         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   10076                 != PackageManager.PERMISSION_GRANTED) {
   10077             throw new SecurityException("Requires permission "
   10078                     + android.Manifest.permission.SHUTDOWN);
   10079         }
   10080 
   10081         boolean timedout = false;
   10082 
   10083         synchronized(this) {
   10084             mShuttingDown = true;
   10085             updateEventDispatchingLocked();
   10086             timedout = mStackSupervisor.shutdownLocked(timeout);
   10087         }
   10088 
   10089         mAppOpsService.shutdown();
   10090         if (mUsageStatsService != null) {
   10091             mUsageStatsService.prepareShutdown();
   10092         }
   10093         mBatteryStatsService.shutdown();
   10094         synchronized (this) {
   10095             mProcessStats.shutdownLocked();
   10096             notifyTaskPersisterLocked(null, true);
   10097         }
   10098 
   10099         return timedout;
   10100     }
   10101 
   10102     public final void activitySlept(IBinder token) {
   10103         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
   10104 
   10105         final long origId = Binder.clearCallingIdentity();
   10106 
   10107         synchronized (this) {
   10108             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10109             if (r != null) {
   10110                 mStackSupervisor.activitySleptLocked(r);
   10111             }
   10112         }
   10113 
   10114         Binder.restoreCallingIdentity(origId);
   10115     }
   10116 
   10117     private String lockScreenShownToString() {
   10118         switch (mLockScreenShown) {
   10119             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
   10120             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
   10121             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
   10122             default: return "Unknown=" + mLockScreenShown;
   10123         }
   10124     }
   10125 
   10126     void logLockScreen(String msg) {
   10127         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
   10128                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
   10129                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
   10130                 + " mSleeping=" + mSleeping);
   10131     }
   10132 
   10133     void startRunningVoiceLocked() {
   10134         if (!mRunningVoice) {
   10135             mRunningVoice = true;
   10136             updateSleepIfNeededLocked();
   10137         }
   10138     }
   10139 
   10140     private void updateEventDispatchingLocked() {
   10141         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   10142     }
   10143 
   10144     public void setLockScreenShown(boolean shown) {
   10145         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   10146                 != PackageManager.PERMISSION_GRANTED) {
   10147             throw new SecurityException("Requires permission "
   10148                     + android.Manifest.permission.DEVICE_POWER);
   10149         }
   10150 
   10151         synchronized(this) {
   10152             long ident = Binder.clearCallingIdentity();
   10153             try {
   10154                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
   10155                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
   10156                 updateSleepIfNeededLocked();
   10157             } finally {
   10158                 Binder.restoreCallingIdentity(ident);
   10159             }
   10160         }
   10161     }
   10162 
   10163     @Override
   10164     public void stopAppSwitches() {
   10165         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10166                 != PackageManager.PERMISSION_GRANTED) {
   10167             throw new SecurityException("Requires permission "
   10168                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10169         }
   10170 
   10171         synchronized(this) {
   10172             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   10173                     + APP_SWITCH_DELAY_TIME;
   10174             mDidAppSwitch = false;
   10175             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10176             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10177             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   10178         }
   10179     }
   10180 
   10181     public void resumeAppSwitches() {
   10182         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10183                 != PackageManager.PERMISSION_GRANTED) {
   10184             throw new SecurityException("Requires permission "
   10185                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10186         }
   10187 
   10188         synchronized(this) {
   10189             // Note that we don't execute any pending app switches... we will
   10190             // let those wait until either the timeout, or the next start
   10191             // activity request.
   10192             mAppSwitchesAllowedTime = 0;
   10193         }
   10194     }
   10195 
   10196     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   10197             int callingPid, int callingUid, String name) {
   10198         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   10199             return true;
   10200         }
   10201 
   10202         int perm = checkComponentPermission(
   10203                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   10204                 sourceUid, -1, true);
   10205         if (perm == PackageManager.PERMISSION_GRANTED) {
   10206             return true;
   10207         }
   10208 
   10209         // If the actual IPC caller is different from the logical source, then
   10210         // also see if they are allowed to control app switches.
   10211         if (callingUid != -1 && callingUid != sourceUid) {
   10212             perm = checkComponentPermission(
   10213                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   10214                     callingUid, -1, true);
   10215             if (perm == PackageManager.PERMISSION_GRANTED) {
   10216                 return true;
   10217             }
   10218         }
   10219 
   10220         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   10221         return false;
   10222     }
   10223 
   10224     public void setDebugApp(String packageName, boolean waitForDebugger,
   10225             boolean persistent) {
   10226         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   10227                 "setDebugApp()");
   10228 
   10229         long ident = Binder.clearCallingIdentity();
   10230         try {
   10231             // Note that this is not really thread safe if there are multiple
   10232             // callers into it at the same time, but that's not a situation we
   10233             // care about.
   10234             if (persistent) {
   10235                 final ContentResolver resolver = mContext.getContentResolver();
   10236                 Settings.Global.putString(
   10237                     resolver, Settings.Global.DEBUG_APP,
   10238                     packageName);
   10239                 Settings.Global.putInt(
   10240                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   10241                     waitForDebugger ? 1 : 0);
   10242             }
   10243 
   10244             synchronized (this) {
   10245                 if (!persistent) {
   10246                     mOrigDebugApp = mDebugApp;
   10247                     mOrigWaitForDebugger = mWaitForDebugger;
   10248                 }
   10249                 mDebugApp = packageName;
   10250                 mWaitForDebugger = waitForDebugger;
   10251                 mDebugTransient = !persistent;
   10252                 if (packageName != null) {
   10253                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   10254                             false, UserHandle.USER_ALL, "set debug app");
   10255                 }
   10256             }
   10257         } finally {
   10258             Binder.restoreCallingIdentity(ident);
   10259         }
   10260     }
   10261 
   10262     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   10263         synchronized (this) {
   10264             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10265             if (!isDebuggable) {
   10266                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10267                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10268                 }
   10269             }
   10270 
   10271             mOpenGlTraceApp = processName;
   10272         }
   10273     }
   10274 
   10275     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   10276         synchronized (this) {
   10277             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10278             if (!isDebuggable) {
   10279                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10280                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10281                 }
   10282             }
   10283             mProfileApp = processName;
   10284             mProfileFile = profilerInfo.profileFile;
   10285             if (mProfileFd != null) {
   10286                 try {
   10287                     mProfileFd.close();
   10288                 } catch (IOException e) {
   10289                 }
   10290                 mProfileFd = null;
   10291             }
   10292             mProfileFd = profilerInfo.profileFd;
   10293             mSamplingInterval = profilerInfo.samplingInterval;
   10294             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   10295             mProfileType = 0;
   10296         }
   10297     }
   10298 
   10299     @Override
   10300     public void setAlwaysFinish(boolean enabled) {
   10301         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   10302                 "setAlwaysFinish()");
   10303 
   10304         Settings.Global.putInt(
   10305                 mContext.getContentResolver(),
   10306                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   10307 
   10308         synchronized (this) {
   10309             mAlwaysFinishActivities = enabled;
   10310         }
   10311     }
   10312 
   10313     @Override
   10314     public void setActivityController(IActivityController controller) {
   10315         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10316                 "setActivityController()");
   10317         synchronized (this) {
   10318             mController = controller;
   10319             Watchdog.getInstance().setActivityController(controller);
   10320         }
   10321     }
   10322 
   10323     @Override
   10324     public void setUserIsMonkey(boolean userIsMonkey) {
   10325         synchronized (this) {
   10326             synchronized (mPidsSelfLocked) {
   10327                 final int callingPid = Binder.getCallingPid();
   10328                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   10329                 if (precessRecord == null) {
   10330                     throw new SecurityException("Unknown process: " + callingPid);
   10331                 }
   10332                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   10333                     throw new SecurityException("Only an instrumentation process "
   10334                             + "with a UiAutomation can call setUserIsMonkey");
   10335                 }
   10336             }
   10337             mUserIsMonkey = userIsMonkey;
   10338         }
   10339     }
   10340 
   10341     @Override
   10342     public boolean isUserAMonkey() {
   10343         synchronized (this) {
   10344             // If there is a controller also implies the user is a monkey.
   10345             return (mUserIsMonkey || mController != null);
   10346         }
   10347     }
   10348 
   10349     public void requestBugReport() {
   10350         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   10351         SystemProperties.set("ctl.start", "bugreport");
   10352     }
   10353 
   10354     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   10355         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   10356     }
   10357 
   10358     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   10359         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   10360             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   10361         }
   10362         return KEY_DISPATCHING_TIMEOUT;
   10363     }
   10364 
   10365     @Override
   10366     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   10367         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10368                 != PackageManager.PERMISSION_GRANTED) {
   10369             throw new SecurityException("Requires permission "
   10370                     + android.Manifest.permission.FILTER_EVENTS);
   10371         }
   10372         ProcessRecord proc;
   10373         long timeout;
   10374         synchronized (this) {
   10375             synchronized (mPidsSelfLocked) {
   10376                 proc = mPidsSelfLocked.get(pid);
   10377             }
   10378             timeout = getInputDispatchingTimeoutLocked(proc);
   10379         }
   10380 
   10381         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   10382             return -1;
   10383         }
   10384 
   10385         return timeout;
   10386     }
   10387 
   10388     /**
   10389      * Handle input dispatching timeouts.
   10390      * Returns whether input dispatching should be aborted or not.
   10391      */
   10392     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   10393             final ActivityRecord activity, final ActivityRecord parent,
   10394             final boolean aboveSystem, String reason) {
   10395         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10396                 != PackageManager.PERMISSION_GRANTED) {
   10397             throw new SecurityException("Requires permission "
   10398                     + android.Manifest.permission.FILTER_EVENTS);
   10399         }
   10400 
   10401         final String annotation;
   10402         if (reason == null) {
   10403             annotation = "Input dispatching timed out";
   10404         } else {
   10405             annotation = "Input dispatching timed out (" + reason + ")";
   10406         }
   10407 
   10408         if (proc != null) {
   10409             synchronized (this) {
   10410                 if (proc.debugging) {
   10411                     return false;
   10412                 }
   10413 
   10414                 if (mDidDexOpt) {
   10415                     // Give more time since we were dexopting.
   10416                     mDidDexOpt = false;
   10417                     return false;
   10418                 }
   10419 
   10420                 if (proc.instrumentationClass != null) {
   10421                     Bundle info = new Bundle();
   10422                     info.putString("shortMsg", "keyDispatchingTimedOut");
   10423                     info.putString("longMsg", annotation);
   10424                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   10425                     return true;
   10426                 }
   10427             }
   10428             mHandler.post(new Runnable() {
   10429                 @Override
   10430                 public void run() {
   10431                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
   10432                 }
   10433             });
   10434         }
   10435 
   10436         return true;
   10437     }
   10438 
   10439     public Bundle getAssistContextExtras(int requestType) {
   10440         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
   10441                 UserHandle.getCallingUserId());
   10442         if (pae == null) {
   10443             return null;
   10444         }
   10445         synchronized (pae) {
   10446             while (!pae.haveResult) {
   10447                 try {
   10448                     pae.wait();
   10449                 } catch (InterruptedException e) {
   10450                 }
   10451             }
   10452             if (pae.result != null) {
   10453                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   10454             }
   10455         }
   10456         synchronized (this) {
   10457             mPendingAssistExtras.remove(pae);
   10458             mHandler.removeCallbacks(pae);
   10459         }
   10460         return pae.extras;
   10461     }
   10462 
   10463     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   10464             int userHandle) {
   10465         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   10466                 "getAssistContextExtras()");
   10467         PendingAssistExtras pae;
   10468         Bundle extras = new Bundle();
   10469         synchronized (this) {
   10470             ActivityRecord activity = getFocusedStack().mResumedActivity;
   10471             if (activity == null) {
   10472                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
   10473                 return null;
   10474             }
   10475             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   10476             if (activity.app == null || activity.app.thread == null) {
   10477                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   10478                 return null;
   10479             }
   10480             if (activity.app.pid == Binder.getCallingPid()) {
   10481                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
   10482                 return null;
   10483             }
   10484             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
   10485             try {
   10486                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   10487                         requestType);
   10488                 mPendingAssistExtras.add(pae);
   10489                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
   10490             } catch (RemoteException e) {
   10491                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   10492                 return null;
   10493             }
   10494             return pae;
   10495         }
   10496     }
   10497 
   10498     public void reportAssistContextExtras(IBinder token, Bundle extras) {
   10499         PendingAssistExtras pae = (PendingAssistExtras)token;
   10500         synchronized (pae) {
   10501             pae.result = extras;
   10502             pae.haveResult = true;
   10503             pae.notifyAll();
   10504             if (pae.intent == null) {
   10505                 // Caller is just waiting for the result.
   10506                 return;
   10507             }
   10508         }
   10509 
   10510         // We are now ready to launch the assist activity.
   10511         synchronized (this) {
   10512             boolean exists = mPendingAssistExtras.remove(pae);
   10513             mHandler.removeCallbacks(pae);
   10514             if (!exists) {
   10515                 // Timed out.
   10516                 return;
   10517             }
   10518         }
   10519         pae.intent.replaceExtras(extras);
   10520         if (pae.hint != null) {
   10521             pae.intent.putExtra(pae.hint, true);
   10522         }
   10523         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10524                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
   10525                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   10526         closeSystemDialogs("assist");
   10527         try {
   10528             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   10529         } catch (ActivityNotFoundException e) {
   10530             Slog.w(TAG, "No activity to handle assist action.", e);
   10531         }
   10532     }
   10533 
   10534     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
   10535         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
   10536     }
   10537 
   10538     public void registerProcessObserver(IProcessObserver observer) {
   10539         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10540                 "registerProcessObserver()");
   10541         synchronized (this) {
   10542             mProcessObservers.register(observer);
   10543         }
   10544     }
   10545 
   10546     @Override
   10547     public void unregisterProcessObserver(IProcessObserver observer) {
   10548         synchronized (this) {
   10549             mProcessObservers.unregister(observer);
   10550         }
   10551     }
   10552 
   10553     @Override
   10554     public boolean convertFromTranslucent(IBinder token) {
   10555         final long origId = Binder.clearCallingIdentity();
   10556         try {
   10557             synchronized (this) {
   10558                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10559                 if (r == null) {
   10560                     return false;
   10561                 }
   10562                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   10563                 if (translucentChanged) {
   10564                     r.task.stack.releaseBackgroundResources();
   10565                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10566                 }
   10567                 mWindowManager.setAppFullscreen(token, true);
   10568                 return translucentChanged;
   10569             }
   10570         } finally {
   10571             Binder.restoreCallingIdentity(origId);
   10572         }
   10573     }
   10574 
   10575     @Override
   10576     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   10577         final long origId = Binder.clearCallingIdentity();
   10578         try {
   10579             synchronized (this) {
   10580                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10581                 if (r == null) {
   10582                     return false;
   10583                 }
   10584                 int index = r.task.mActivities.lastIndexOf(r);
   10585                 if (index > 0) {
   10586                     ActivityRecord under = r.task.mActivities.get(index - 1);
   10587                     under.returningOptions = options;
   10588                 }
   10589                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   10590                 if (translucentChanged) {
   10591                     r.task.stack.convertToTranslucent(r);
   10592                 }
   10593                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10594                 mWindowManager.setAppFullscreen(token, false);
   10595                 return translucentChanged;
   10596             }
   10597         } finally {
   10598             Binder.restoreCallingIdentity(origId);
   10599         }
   10600     }
   10601 
   10602     @Override
   10603     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   10604         final long origId = Binder.clearCallingIdentity();
   10605         try {
   10606             synchronized (this) {
   10607                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10608                 if (r != null) {
   10609                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   10610                 }
   10611             }
   10612             return false;
   10613         } finally {
   10614             Binder.restoreCallingIdentity(origId);
   10615         }
   10616     }
   10617 
   10618     @Override
   10619     public boolean isBackgroundVisibleBehind(IBinder token) {
   10620         final long origId = Binder.clearCallingIdentity();
   10621         try {
   10622             synchronized (this) {
   10623                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   10624                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   10625                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
   10626                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   10627                 return visible;
   10628             }
   10629         } finally {
   10630             Binder.restoreCallingIdentity(origId);
   10631         }
   10632     }
   10633 
   10634     @Override
   10635     public ActivityOptions getActivityOptions(IBinder token) {
   10636         final long origId = Binder.clearCallingIdentity();
   10637         try {
   10638             synchronized (this) {
   10639                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10640                 if (r != null) {
   10641                     final ActivityOptions activityOptions = r.pendingOptions;
   10642                     r.pendingOptions = null;
   10643                     return activityOptions;
   10644                 }
   10645                 return null;
   10646             }
   10647         } finally {
   10648             Binder.restoreCallingIdentity(origId);
   10649         }
   10650     }
   10651 
   10652     @Override
   10653     public void setImmersive(IBinder token, boolean immersive) {
   10654         synchronized(this) {
   10655             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10656             if (r == null) {
   10657                 throw new IllegalArgumentException();
   10658             }
   10659             r.immersive = immersive;
   10660 
   10661             // update associated state if we're frontmost
   10662             if (r == mFocusedActivity) {
   10663                 if (DEBUG_IMMERSIVE) {
   10664                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   10665                 }
   10666                 applyUpdateLockStateLocked(r);
   10667             }
   10668         }
   10669     }
   10670 
   10671     @Override
   10672     public boolean isImmersive(IBinder token) {
   10673         synchronized (this) {
   10674             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10675             if (r == null) {
   10676                 throw new IllegalArgumentException();
   10677             }
   10678             return r.immersive;
   10679         }
   10680     }
   10681 
   10682     public boolean isTopActivityImmersive() {
   10683         enforceNotIsolatedCaller("startActivity");
   10684         synchronized (this) {
   10685             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
   10686             return (r != null) ? r.immersive : false;
   10687         }
   10688     }
   10689 
   10690     @Override
   10691     public boolean isTopOfTask(IBinder token) {
   10692         synchronized (this) {
   10693             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10694             if (r == null) {
   10695                 throw new IllegalArgumentException();
   10696             }
   10697             return r.task.getTopActivity() == r;
   10698         }
   10699     }
   10700 
   10701     public final void enterSafeMode() {
   10702         synchronized(this) {
   10703             // It only makes sense to do this before the system is ready
   10704             // and started launching other packages.
   10705             if (!mSystemReady) {
   10706                 try {
   10707                     AppGlobals.getPackageManager().enterSafeMode();
   10708                 } catch (RemoteException e) {
   10709                 }
   10710             }
   10711 
   10712             mSafeMode = true;
   10713         }
   10714     }
   10715 
   10716     public final void showSafeModeOverlay() {
   10717         View v = LayoutInflater.from(mContext).inflate(
   10718                 com.android.internal.R.layout.safe_mode, null);
   10719         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   10720         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   10721         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   10722         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   10723         lp.gravity = Gravity.BOTTOM | Gravity.START;
   10724         lp.format = v.getBackground().getOpacity();
   10725         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   10726                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   10727         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   10728         ((WindowManager)mContext.getSystemService(
   10729                 Context.WINDOW_SERVICE)).addView(v, lp);
   10730     }
   10731 
   10732     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
   10733         if (!(sender instanceof PendingIntentRecord)) {
   10734             return;
   10735         }
   10736         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10737         synchronized (stats) {
   10738             if (mBatteryStatsService.isOnBattery()) {
   10739                 mBatteryStatsService.enforceCallingPermission();
   10740                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   10741                 int MY_UID = Binder.getCallingUid();
   10742                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   10743                 BatteryStatsImpl.Uid.Pkg pkg =
   10744                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   10745                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   10746                 pkg.incWakeupsLocked();
   10747             }
   10748         }
   10749     }
   10750 
   10751     public boolean killPids(int[] pids, String pReason, boolean secure) {
   10752         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10753             throw new SecurityException("killPids only available to the system");
   10754         }
   10755         String reason = (pReason == null) ? "Unknown" : pReason;
   10756         // XXX Note: don't acquire main activity lock here, because the window
   10757         // manager calls in with its locks held.
   10758 
   10759         boolean killed = false;
   10760         synchronized (mPidsSelfLocked) {
   10761             int[] types = new int[pids.length];
   10762             int worstType = 0;
   10763             for (int i=0; i<pids.length; i++) {
   10764                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10765                 if (proc != null) {
   10766                     int type = proc.setAdj;
   10767                     types[i] = type;
   10768                     if (type > worstType) {
   10769                         worstType = type;
   10770                     }
   10771                 }
   10772             }
   10773 
   10774             // If the worst oom_adj is somewhere in the cached proc LRU range,
   10775             // then constrain it so we will kill all cached procs.
   10776             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   10777                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   10778                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   10779             }
   10780 
   10781             // If this is not a secure call, don't let it kill processes that
   10782             // are important.
   10783             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   10784                 worstType = ProcessList.SERVICE_ADJ;
   10785             }
   10786 
   10787             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   10788             for (int i=0; i<pids.length; i++) {
   10789                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10790                 if (proc == null) {
   10791                     continue;
   10792                 }
   10793                 int adj = proc.setAdj;
   10794                 if (adj >= worstType && !proc.killedByAm) {
   10795                     proc.kill(reason, true);
   10796                     killed = true;
   10797                 }
   10798             }
   10799         }
   10800         return killed;
   10801     }
   10802 
   10803     @Override
   10804     public void killUid(int uid, String reason) {
   10805         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10806             throw new SecurityException("killUid only available to the system");
   10807         }
   10808         synchronized (this) {
   10809             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   10810                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   10811                     reason != null ? reason : "kill uid");
   10812         }
   10813     }
   10814 
   10815     @Override
   10816     public boolean killProcessesBelowForeground(String reason) {
   10817         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10818             throw new SecurityException("killProcessesBelowForeground() only available to system");
   10819         }
   10820 
   10821         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   10822     }
   10823 
   10824     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   10825         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10826             throw new SecurityException("killProcessesBelowAdj() only available to system");
   10827         }
   10828 
   10829         boolean killed = false;
   10830         synchronized (mPidsSelfLocked) {
   10831             final int size = mPidsSelfLocked.size();
   10832             for (int i = 0; i < size; i++) {
   10833                 final int pid = mPidsSelfLocked.keyAt(i);
   10834                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   10835                 if (proc == null) continue;
   10836 
   10837                 final int adj = proc.setAdj;
   10838                 if (adj > belowAdj && !proc.killedByAm) {
   10839                     proc.kill(reason, true);
   10840                     killed = true;
   10841                 }
   10842             }
   10843         }
   10844         return killed;
   10845     }
   10846 
   10847     @Override
   10848     public void hang(final IBinder who, boolean allowRestart) {
   10849         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10850                 != PackageManager.PERMISSION_GRANTED) {
   10851             throw new SecurityException("Requires permission "
   10852                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10853         }
   10854 
   10855         final IBinder.DeathRecipient death = new DeathRecipient() {
   10856             @Override
   10857             public void binderDied() {
   10858                 synchronized (this) {
   10859                     notifyAll();
   10860                 }
   10861             }
   10862         };
   10863 
   10864         try {
   10865             who.linkToDeath(death, 0);
   10866         } catch (RemoteException e) {
   10867             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   10868             return;
   10869         }
   10870 
   10871         synchronized (this) {
   10872             Watchdog.getInstance().setAllowRestart(allowRestart);
   10873             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   10874             synchronized (death) {
   10875                 while (who.isBinderAlive()) {
   10876                     try {
   10877                         death.wait();
   10878                     } catch (InterruptedException e) {
   10879                     }
   10880                 }
   10881             }
   10882             Watchdog.getInstance().setAllowRestart(true);
   10883         }
   10884     }
   10885 
   10886     @Override
   10887     public void restart() {
   10888         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10889                 != PackageManager.PERMISSION_GRANTED) {
   10890             throw new SecurityException("Requires permission "
   10891                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10892         }
   10893 
   10894         Log.i(TAG, "Sending shutdown broadcast...");
   10895 
   10896         BroadcastReceiver br = new BroadcastReceiver() {
   10897             @Override public void onReceive(Context context, Intent intent) {
   10898                 // Now the broadcast is done, finish up the low-level shutdown.
   10899                 Log.i(TAG, "Shutting down activity manager...");
   10900                 shutdown(10000);
   10901                 Log.i(TAG, "Shutdown complete, restarting!");
   10902                 Process.killProcess(Process.myPid());
   10903                 System.exit(10);
   10904             }
   10905         };
   10906 
   10907         // First send the high-level shut down broadcast.
   10908         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   10909         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   10910         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   10911         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   10912         mContext.sendOrderedBroadcastAsUser(intent,
   10913                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   10914         */
   10915         br.onReceive(mContext, intent);
   10916     }
   10917 
   10918     private long getLowRamTimeSinceIdle(long now) {
   10919         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   10920     }
   10921 
   10922     @Override
   10923     public void performIdleMaintenance() {
   10924         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10925                 != PackageManager.PERMISSION_GRANTED) {
   10926             throw new SecurityException("Requires permission "
   10927                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10928         }
   10929 
   10930         synchronized (this) {
   10931             final long now = SystemClock.uptimeMillis();
   10932             final long timeSinceLastIdle = now - mLastIdleTime;
   10933             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   10934             mLastIdleTime = now;
   10935             mLowRamTimeSinceLastIdle = 0;
   10936             if (mLowRamStartTime != 0) {
   10937                 mLowRamStartTime = now;
   10938             }
   10939 
   10940             StringBuilder sb = new StringBuilder(128);
   10941             sb.append("Idle maintenance over ");
   10942             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   10943             sb.append(" low RAM for ");
   10944             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   10945             Slog.i(TAG, sb.toString());
   10946 
   10947             // If at least 1/3 of our time since the last idle period has been spent
   10948             // with RAM low, then we want to kill processes.
   10949             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   10950 
   10951             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   10952                 ProcessRecord proc = mLruProcesses.get(i);
   10953                 if (proc.notCachedSinceIdle) {
   10954                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
   10955                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   10956                         if (doKilling && proc.initialIdlePss != 0
   10957                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   10958                             sb = new StringBuilder(128);
   10959                             sb.append("Kill");
   10960                             sb.append(proc.processName);
   10961                             sb.append(" in idle maint: pss=");
   10962                             sb.append(proc.lastPss);
   10963                             sb.append(", initialPss=");
   10964                             sb.append(proc.initialIdlePss);
   10965                             sb.append(", period=");
   10966                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   10967                             sb.append(", lowRamPeriod=");
   10968                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   10969                             Slog.wtfQuiet(TAG, sb.toString());
   10970                             proc.kill("idle maint (pss " + proc.lastPss
   10971                                     + " from " + proc.initialIdlePss + ")", true);
   10972                         }
   10973                     }
   10974                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
   10975                     proc.notCachedSinceIdle = true;
   10976                     proc.initialIdlePss = 0;
   10977                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
   10978                             mTestPssMode, isSleeping(), now);
   10979                 }
   10980             }
   10981 
   10982             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   10983             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   10984         }
   10985     }
   10986 
   10987     private void retrieveSettings() {
   10988         final ContentResolver resolver = mContext.getContentResolver();
   10989         String debugApp = Settings.Global.getString(
   10990             resolver, Settings.Global.DEBUG_APP);
   10991         boolean waitForDebugger = Settings.Global.getInt(
   10992             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   10993         boolean alwaysFinishActivities = Settings.Global.getInt(
   10994             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   10995         boolean forceRtl = Settings.Global.getInt(
   10996                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
   10997         // Transfer any global setting for forcing RTL layout, into a System Property
   10998         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   10999 
   11000         Configuration configuration = new Configuration();
   11001         Settings.System.getConfiguration(resolver, configuration);
   11002         if (forceRtl) {
   11003             // This will take care of setting the correct layout direction flags
   11004             configuration.setLayoutDirection(configuration.locale);
   11005         }
   11006 
   11007         synchronized (this) {
   11008             mDebugApp = mOrigDebugApp = debugApp;
   11009             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   11010             mAlwaysFinishActivities = alwaysFinishActivities;
   11011             // This happens before any activities are started, so we can
   11012             // change mConfiguration in-place.
   11013             updateConfigurationLocked(configuration, null, false, true);
   11014             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   11015         }
   11016     }
   11017 
   11018     /** Loads resources after the current configuration has been set. */
   11019     private void loadResourcesOnSystemReady() {
   11020         final Resources res = mContext.getResources();
   11021         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   11022         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
   11023         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
   11024     }
   11025 
   11026     public boolean testIsSystemReady() {
   11027         // no need to synchronize(this) just to read & return the value
   11028         return mSystemReady;
   11029     }
   11030 
   11031     private static File getCalledPreBootReceiversFile() {
   11032         File dataDir = Environment.getDataDirectory();
   11033         File systemDir = new File(dataDir, "system");
   11034         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
   11035         return fname;
   11036     }
   11037 
   11038     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   11039         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   11040         File file = getCalledPreBootReceiversFile();
   11041         FileInputStream fis = null;
   11042         try {
   11043             fis = new FileInputStream(file);
   11044             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   11045             int fvers = dis.readInt();
   11046             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
   11047                 String vers = dis.readUTF();
   11048                 String codename = dis.readUTF();
   11049                 String build = dis.readUTF();
   11050                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   11051                         && android.os.Build.VERSION.CODENAME.equals(codename)
   11052                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   11053                     int num = dis.readInt();
   11054                     while (num > 0) {
   11055                         num--;
   11056                         String pkg = dis.readUTF();
   11057                         String cls = dis.readUTF();
   11058                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   11059                     }
   11060                 }
   11061             }
   11062         } catch (FileNotFoundException e) {
   11063         } catch (IOException e) {
   11064             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   11065         } finally {
   11066             if (fis != null) {
   11067                 try {
   11068                     fis.close();
   11069                 } catch (IOException e) {
   11070                 }
   11071             }
   11072         }
   11073         return lastDoneReceivers;
   11074     }
   11075 
   11076     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   11077         File file = getCalledPreBootReceiversFile();
   11078         FileOutputStream fos = null;
   11079         DataOutputStream dos = null;
   11080         try {
   11081             fos = new FileOutputStream(file);
   11082             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   11083             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
   11084             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   11085             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   11086             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   11087             dos.writeInt(list.size());
   11088             for (int i=0; i<list.size(); i++) {
   11089                 dos.writeUTF(list.get(i).getPackageName());
   11090                 dos.writeUTF(list.get(i).getClassName());
   11091             }
   11092         } catch (IOException e) {
   11093             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   11094             file.delete();
   11095         } finally {
   11096             FileUtils.sync(fos);
   11097             if (dos != null) {
   11098                 try {
   11099                     dos.close();
   11100                 } catch (IOException e) {
   11101                     // TODO Auto-generated catch block
   11102                     e.printStackTrace();
   11103                 }
   11104             }
   11105         }
   11106     }
   11107 
   11108     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
   11109             ArrayList<ComponentName> doneReceivers, int userId) {
   11110         boolean waitingUpdate = false;
   11111         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   11112         List<ResolveInfo> ris = null;
   11113         try {
   11114             ris = AppGlobals.getPackageManager().queryIntentReceivers(
   11115                     intent, null, 0, userId);
   11116         } catch (RemoteException e) {
   11117         }
   11118         if (ris != null) {
   11119             for (int i=ris.size()-1; i>=0; i--) {
   11120                 if ((ris.get(i).activityInfo.applicationInfo.flags
   11121                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
   11122                     ris.remove(i);
   11123                 }
   11124             }
   11125             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   11126 
   11127             // For User 0, load the version number. When delivering to a new user, deliver
   11128             // to all receivers.
   11129             if (userId == UserHandle.USER_OWNER) {
   11130                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   11131                 for (int i=0; i<ris.size(); i++) {
   11132                     ActivityInfo ai = ris.get(i).activityInfo;
   11133                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11134                     if (lastDoneReceivers.contains(comp)) {
   11135                         // We already did the pre boot receiver for this app with the current
   11136                         // platform version, so don't do it again...
   11137                         ris.remove(i);
   11138                         i--;
   11139                         // ...however, do keep it as one that has been done, so we don't
   11140                         // forget about it when rewriting the file of last done receivers.
   11141                         doneReceivers.add(comp);
   11142                     }
   11143                 }
   11144             }
   11145 
   11146             // If primary user, send broadcast to all available users, else just to userId
   11147             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
   11148                     : new int[] { userId };
   11149             for (int i = 0; i < ris.size(); i++) {
   11150                 ActivityInfo ai = ris.get(i).activityInfo;
   11151                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11152                 doneReceivers.add(comp);
   11153                 intent.setComponent(comp);
   11154                 for (int j=0; j<users.length; j++) {
   11155                     IIntentReceiver finisher = null;
   11156                     // On last receiver and user, set up a completion callback
   11157                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
   11158                         finisher = new IIntentReceiver.Stub() {
   11159                             public void performReceive(Intent intent, int resultCode,
   11160                                     String data, Bundle extras, boolean ordered,
   11161                                     boolean sticky, int sendingUser) {
   11162                                 // The raw IIntentReceiver interface is called
   11163                                 // with the AM lock held, so redispatch to
   11164                                 // execute our code without the lock.
   11165                                 mHandler.post(onFinishCallback);
   11166                             }
   11167                         };
   11168                     }
   11169                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
   11170                             + " for user " + users[j]);
   11171                     broadcastIntentLocked(null, null, intent, null, finisher,
   11172                             0, null, null, null, AppOpsManager.OP_NONE,
   11173                             true, false, MY_PID, Process.SYSTEM_UID,
   11174                             users[j]);
   11175                     if (finisher != null) {
   11176                         waitingUpdate = true;
   11177                     }
   11178                 }
   11179             }
   11180         }
   11181 
   11182         return waitingUpdate;
   11183     }
   11184 
   11185     public void systemReady(final Runnable goingCallback) {
   11186         synchronized(this) {
   11187             if (mSystemReady) {
   11188                 // If we're done calling all the receivers, run the next "boot phase" passed in
   11189                 // by the SystemServer
   11190                 if (goingCallback != null) {
   11191                     goingCallback.run();
   11192                 }
   11193                 return;
   11194             }
   11195 
   11196             // Make sure we have the current profile info, since it is needed for
   11197             // security checks.
   11198             updateCurrentProfileIdsLocked();
   11199 
   11200             if (mRecentTasks == null) {
   11201                 mRecentTasks = mTaskPersister.restoreTasksLocked();
   11202                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
   11203                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
   11204                 mTaskPersister.startPersisting();
   11205             }
   11206 
   11207             // Check to see if there are any update receivers to run.
   11208             if (!mDidUpdate) {
   11209                 if (mWaitingUpdate) {
   11210                     return;
   11211                 }
   11212                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   11213                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
   11214                     public void run() {
   11215                         synchronized (ActivityManagerService.this) {
   11216                             mDidUpdate = true;
   11217                         }
   11218                         writeLastDonePreBootReceivers(doneReceivers);
   11219                         showBootMessage(mContext.getText(R.string.android_upgrading_complete),
   11220                                 false);
   11221                         systemReady(goingCallback);
   11222                     }
   11223                 }, doneReceivers, UserHandle.USER_OWNER);
   11224 
   11225                 if (mWaitingUpdate) {
   11226                     return;
   11227                 }
   11228                 mDidUpdate = true;
   11229             }
   11230 
   11231             mAppOpsService.systemReady();
   11232             mSystemReady = true;
   11233         }
   11234 
   11235         ArrayList<ProcessRecord> procsToKill = null;
   11236         synchronized(mPidsSelfLocked) {
   11237             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   11238                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   11239                 if (!isAllowedWhileBooting(proc.info)){
   11240                     if (procsToKill == null) {
   11241                         procsToKill = new ArrayList<ProcessRecord>();
   11242                     }
   11243                     procsToKill.add(proc);
   11244                 }
   11245             }
   11246         }
   11247 
   11248         synchronized(this) {
   11249             if (procsToKill != null) {
   11250                 for (int i=procsToKill.size()-1; i>=0; i--) {
   11251                     ProcessRecord proc = procsToKill.get(i);
   11252                     Slog.i(TAG, "Removing system update proc: " + proc);
   11253                     removeProcessLocked(proc, true, false, "system update done");
   11254                 }
   11255             }
   11256 
   11257             // Now that we have cleaned up any update processes, we
   11258             // are ready to start launching real processes and know that
   11259             // we won't trample on them any more.
   11260             mProcessesReady = true;
   11261         }
   11262 
   11263         Slog.i(TAG, "System now ready");
   11264         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   11265             SystemClock.uptimeMillis());
   11266 
   11267         synchronized(this) {
   11268             // Make sure we have no pre-ready processes sitting around.
   11269 
   11270             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11271                 ResolveInfo ri = mContext.getPackageManager()
   11272                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   11273                                 STOCK_PM_FLAGS);
   11274                 CharSequence errorMsg = null;
   11275                 if (ri != null) {
   11276                     ActivityInfo ai = ri.activityInfo;
   11277                     ApplicationInfo app = ai.applicationInfo;
   11278                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   11279                         mTopAction = Intent.ACTION_FACTORY_TEST;
   11280                         mTopData = null;
   11281                         mTopComponent = new ComponentName(app.packageName,
   11282                                 ai.name);
   11283                     } else {
   11284                         errorMsg = mContext.getResources().getText(
   11285                                 com.android.internal.R.string.factorytest_not_system);
   11286                     }
   11287                 } else {
   11288                     errorMsg = mContext.getResources().getText(
   11289                             com.android.internal.R.string.factorytest_no_action);
   11290                 }
   11291                 if (errorMsg != null) {
   11292                     mTopAction = null;
   11293                     mTopData = null;
   11294                     mTopComponent = null;
   11295                     Message msg = Message.obtain();
   11296                     msg.what = SHOW_FACTORY_ERROR_MSG;
   11297                     msg.getData().putCharSequence("msg", errorMsg);
   11298                     mHandler.sendMessage(msg);
   11299                 }
   11300             }
   11301         }
   11302 
   11303         retrieveSettings();
   11304         loadResourcesOnSystemReady();
   11305 
   11306         synchronized (this) {
   11307             readGrantedUriPermissionsLocked();
   11308         }
   11309 
   11310         if (goingCallback != null) goingCallback.run();
   11311 
   11312         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   11313                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11314         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   11315                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11316         mSystemServiceManager.startUser(mCurrentUserId);
   11317 
   11318         synchronized (this) {
   11319             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11320                 try {
   11321                     List apps = AppGlobals.getPackageManager().
   11322                         getPersistentApplications(STOCK_PM_FLAGS);
   11323                     if (apps != null) {
   11324                         int N = apps.size();
   11325                         int i;
   11326                         for (i=0; i<N; i++) {
   11327                             ApplicationInfo info
   11328                                 = (ApplicationInfo)apps.get(i);
   11329                             if (info != null &&
   11330                                     !info.packageName.equals("android")) {
   11331                                 addAppLocked(info, false, null /* ABI override */);
   11332                             }
   11333                         }
   11334                     }
   11335                 } catch (RemoteException ex) {
   11336                     // pm is in same process, this will never happen.
   11337                 }
   11338             }
   11339 
   11340             // Start up initial activity.
   11341             mBooting = true;
   11342             startHomeActivityLocked(mCurrentUserId, "systemReady");
   11343 
   11344             try {
   11345                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   11346                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
   11347                             + " data partition or your device will be unstable.");
   11348                     mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
   11349                 }
   11350             } catch (RemoteException e) {
   11351             }
   11352 
   11353             if (!Build.isFingerprintConsistent()) {
   11354                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
   11355                 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
   11356             }
   11357 
   11358             long ident = Binder.clearCallingIdentity();
   11359             try {
   11360                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   11361                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   11362                         | Intent.FLAG_RECEIVER_FOREGROUND);
   11363                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11364                 broadcastIntentLocked(null, null, intent,
   11365                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   11366                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   11367                 intent = new Intent(Intent.ACTION_USER_STARTING);
   11368                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   11369                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11370                 broadcastIntentLocked(null, null, intent,
   11371                         null, new IIntentReceiver.Stub() {
   11372                             @Override
   11373                             public void performReceive(Intent intent, int resultCode, String data,
   11374                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   11375                                     throws RemoteException {
   11376                             }
   11377                         }, 0, null, null,
   11378                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   11379                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   11380             } catch (Throwable t) {
   11381                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   11382             } finally {
   11383                 Binder.restoreCallingIdentity(ident);
   11384             }
   11385             mStackSupervisor.resumeTopActivitiesLocked();
   11386             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   11387         }
   11388     }
   11389 
   11390     private boolean makeAppCrashingLocked(ProcessRecord app,
   11391             String shortMsg, String longMsg, String stackTrace) {
   11392         app.crashing = true;
   11393         app.crashingReport = generateProcessError(app,
   11394                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   11395         startAppProblemLocked(app);
   11396         app.stopFreezingAllLocked();
   11397         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
   11398     }
   11399 
   11400     private void makeAppNotRespondingLocked(ProcessRecord app,
   11401             String activity, String shortMsg, String longMsg) {
   11402         app.notResponding = true;
   11403         app.notRespondingReport = generateProcessError(app,
   11404                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   11405                 activity, shortMsg, longMsg, null);
   11406         startAppProblemLocked(app);
   11407         app.stopFreezingAllLocked();
   11408     }
   11409 
   11410     /**
   11411      * Generate a process error record, suitable for attachment to a ProcessRecord.
   11412      *
   11413      * @param app The ProcessRecord in which the error occurred.
   11414      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   11415      *                      ActivityManager.AppErrorStateInfo
   11416      * @param activity The activity associated with the crash, if known.
   11417      * @param shortMsg Short message describing the crash.
   11418      * @param longMsg Long message describing the crash.
   11419      * @param stackTrace Full crash stack trace, may be null.
   11420      *
   11421      * @return Returns a fully-formed AppErrorStateInfo record.
   11422      */
   11423     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   11424             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   11425         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   11426 
   11427         report.condition = condition;
   11428         report.processName = app.processName;
   11429         report.pid = app.pid;
   11430         report.uid = app.info.uid;
   11431         report.tag = activity;
   11432         report.shortMsg = shortMsg;
   11433         report.longMsg = longMsg;
   11434         report.stackTrace = stackTrace;
   11435 
   11436         return report;
   11437     }
   11438 
   11439     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   11440         synchronized (this) {
   11441             app.crashing = false;
   11442             app.crashingReport = null;
   11443             app.notResponding = false;
   11444             app.notRespondingReport = null;
   11445             if (app.anrDialog == fromDialog) {
   11446                 app.anrDialog = null;
   11447             }
   11448             if (app.waitDialog == fromDialog) {
   11449                 app.waitDialog = null;
   11450             }
   11451             if (app.pid > 0 && app.pid != MY_PID) {
   11452                 handleAppCrashLocked(app, null, null, null);
   11453                 app.kill("user request after error", true);
   11454             }
   11455         }
   11456     }
   11457 
   11458     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
   11459             String stackTrace) {
   11460         long now = SystemClock.uptimeMillis();
   11461 
   11462         Long crashTime;
   11463         if (!app.isolated) {
   11464             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   11465         } else {
   11466             crashTime = null;
   11467         }
   11468         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   11469             // This process loses!
   11470             Slog.w(TAG, "Process " + app.info.processName
   11471                     + " has crashed too many times: killing!");
   11472             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   11473                     app.userId, app.info.processName, app.uid);
   11474             mStackSupervisor.handleAppCrashLocked(app);
   11475             if (!app.persistent) {
   11476                 // We don't want to start this process again until the user
   11477                 // explicitly does so...  but for persistent process, we really
   11478                 // need to keep it running.  If a persistent process is actually
   11479                 // repeatedly crashing, then badness for everyone.
   11480                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   11481                         app.info.processName);
   11482                 if (!app.isolated) {
   11483                     // XXX We don't have a way to mark isolated processes
   11484                     // as bad, since they don't have a peristent identity.
   11485                     mBadProcesses.put(app.info.processName, app.uid,
   11486                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
   11487                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   11488                 }
   11489                 app.bad = true;
   11490                 app.removed = true;
   11491                 // Don't let services in this process be restarted and potentially
   11492                 // annoy the user repeatedly.  Unless it is persistent, since those
   11493                 // processes run critical code.
   11494                 removeProcessLocked(app, false, false, "crash");
   11495                 mStackSupervisor.resumeTopActivitiesLocked();
   11496                 return false;
   11497             }
   11498             mStackSupervisor.resumeTopActivitiesLocked();
   11499         } else {
   11500             mStackSupervisor.finishTopRunningActivityLocked(app);
   11501         }
   11502 
   11503         // Bump up the crash count of any services currently running in the proc.
   11504         for (int i=app.services.size()-1; i>=0; i--) {
   11505             // Any services running in the application need to be placed
   11506             // back in the pending list.
   11507             ServiceRecord sr = app.services.valueAt(i);
   11508             sr.crashCount++;
   11509         }
   11510 
   11511         // If the crashing process is what we consider to be the "home process" and it has been
   11512         // replaced by a third-party app, clear the package preferred activities from packages
   11513         // with a home activity running in the process to prevent a repeatedly crashing app
   11514         // from blocking the user to manually clear the list.
   11515         final ArrayList<ActivityRecord> activities = app.activities;
   11516         if (app == mHomeProcess && activities.size() > 0
   11517                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   11518             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   11519                 final ActivityRecord r = activities.get(activityNdx);
   11520                 if (r.isHomeActivity()) {
   11521                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   11522                     try {
   11523                         ActivityThread.getPackageManager()
   11524                                 .clearPackagePreferredActivities(r.packageName);
   11525                     } catch (RemoteException c) {
   11526                         // pm is in same process, this will never happen.
   11527                     }
   11528                 }
   11529             }
   11530         }
   11531 
   11532         if (!app.isolated) {
   11533             // XXX Can't keep track of crash times for isolated processes,
   11534             // because they don't have a perisistent identity.
   11535             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   11536         }
   11537 
   11538         if (app.crashHandler != null) mHandler.post(app.crashHandler);
   11539         return true;
   11540     }
   11541 
   11542     void startAppProblemLocked(ProcessRecord app) {
   11543         // If this app is not running under the current user, then we
   11544         // can't give it a report button because that would require
   11545         // launching the report UI under a different user.
   11546         app.errorReportReceiver = null;
   11547 
   11548         for (int userId : mCurrentProfileIds) {
   11549             if (app.userId == userId) {
   11550                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   11551                         mContext, app.info.packageName, app.info.flags);
   11552             }
   11553         }
   11554         skipCurrentReceiverLocked(app);
   11555     }
   11556 
   11557     void skipCurrentReceiverLocked(ProcessRecord app) {
   11558         for (BroadcastQueue queue : mBroadcastQueues) {
   11559             queue.skipCurrentReceiverLocked(app);
   11560         }
   11561     }
   11562 
   11563     /**
   11564      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   11565      * The application process will exit immediately after this call returns.
   11566      * @param app object of the crashing app, null for the system server
   11567      * @param crashInfo describing the exception
   11568      */
   11569     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   11570         ProcessRecord r = findAppProcess(app, "Crash");
   11571         final String processName = app == null ? "system_server"
   11572                 : (r == null ? "unknown" : r.processName);
   11573 
   11574         handleApplicationCrashInner("crash", r, processName, crashInfo);
   11575     }
   11576 
   11577     /* Native crash reporting uses this inner version because it needs to be somewhat
   11578      * decoupled from the AM-managed cleanup lifecycle
   11579      */
   11580     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   11581             ApplicationErrorReport.CrashInfo crashInfo) {
   11582         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   11583                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   11584                 r == null ? -1 : r.info.flags,
   11585                 crashInfo.exceptionClassName,
   11586                 crashInfo.exceptionMessage,
   11587                 crashInfo.throwFileName,
   11588                 crashInfo.throwLineNumber);
   11589 
   11590         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   11591 
   11592         crashApplication(r, crashInfo);
   11593     }
   11594 
   11595     public void handleApplicationStrictModeViolation(
   11596             IBinder app,
   11597             int violationMask,
   11598             StrictMode.ViolationInfo info) {
   11599         ProcessRecord r = findAppProcess(app, "StrictMode");
   11600         if (r == null) {
   11601             return;
   11602         }
   11603 
   11604         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   11605             Integer stackFingerprint = info.hashCode();
   11606             boolean logIt = true;
   11607             synchronized (mAlreadyLoggedViolatedStacks) {
   11608                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   11609                     logIt = false;
   11610                     // TODO: sub-sample into EventLog for these, with
   11611                     // the info.durationMillis?  Then we'd get
   11612                     // the relative pain numbers, without logging all
   11613                     // the stack traces repeatedly.  We'd want to do
   11614                     // likewise in the client code, which also does
   11615                     // dup suppression, before the Binder call.
   11616                 } else {
   11617                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   11618                         mAlreadyLoggedViolatedStacks.clear();
   11619                     }
   11620                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   11621                 }
   11622             }
   11623             if (logIt) {
   11624                 logStrictModeViolationToDropBox(r, info);
   11625             }
   11626         }
   11627 
   11628         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   11629             AppErrorResult result = new AppErrorResult();
   11630             synchronized (this) {
   11631                 final long origId = Binder.clearCallingIdentity();
   11632 
   11633                 Message msg = Message.obtain();
   11634                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   11635                 HashMap<String, Object> data = new HashMap<String, Object>();
   11636                 data.put("result", result);
   11637                 data.put("app", r);
   11638                 data.put("violationMask", violationMask);
   11639                 data.put("info", info);
   11640                 msg.obj = data;
   11641                 mHandler.sendMessage(msg);
   11642 
   11643                 Binder.restoreCallingIdentity(origId);
   11644             }
   11645             int res = result.get();
   11646             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   11647         }
   11648     }
   11649 
   11650     // Depending on the policy in effect, there could be a bunch of
   11651     // these in quick succession so we try to batch these together to
   11652     // minimize disk writes, number of dropbox entries, and maximize
   11653     // compression, by having more fewer, larger records.
   11654     private void logStrictModeViolationToDropBox(
   11655             ProcessRecord process,
   11656             StrictMode.ViolationInfo info) {
   11657         if (info == null) {
   11658             return;
   11659         }
   11660         final boolean isSystemApp = process == null ||
   11661                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   11662                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   11663         final String processName = process == null ? "unknown" : process.processName;
   11664         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   11665         final DropBoxManager dbox = (DropBoxManager)
   11666                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11667 
   11668         // Exit early if the dropbox isn't configured to accept this report type.
   11669         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11670 
   11671         boolean bufferWasEmpty;
   11672         boolean needsFlush;
   11673         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   11674         synchronized (sb) {
   11675             bufferWasEmpty = sb.length() == 0;
   11676             appendDropBoxProcessHeaders(process, processName, sb);
   11677             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11678             sb.append("System-App: ").append(isSystemApp).append("\n");
   11679             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   11680             if (info.violationNumThisLoop != 0) {
   11681                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   11682             }
   11683             if (info.numAnimationsRunning != 0) {
   11684                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   11685             }
   11686             if (info.broadcastIntentAction != null) {
   11687                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   11688             }
   11689             if (info.durationMillis != -1) {
   11690                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   11691             }
   11692             if (info.numInstances != -1) {
   11693                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   11694             }
   11695             if (info.tags != null) {
   11696                 for (String tag : info.tags) {
   11697                     sb.append("Span-Tag: ").append(tag).append("\n");
   11698                 }
   11699             }
   11700             sb.append("\n");
   11701             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   11702                 sb.append(info.crashInfo.stackTrace);
   11703             }
   11704             sb.append("\n");
   11705 
   11706             // Only buffer up to ~64k.  Various logging bits truncate
   11707             // things at 128k.
   11708             needsFlush = (sb.length() > 64 * 1024);
   11709         }
   11710 
   11711         // Flush immediately if the buffer's grown too large, or this
   11712         // is a non-system app.  Non-system apps are isolated with a
   11713         // different tag & policy and not batched.
   11714         //
   11715         // Batching is useful during internal testing with
   11716         // StrictMode settings turned up high.  Without batching,
   11717         // thousands of separate files could be created on boot.
   11718         if (!isSystemApp || needsFlush) {
   11719             new Thread("Error dump: " + dropboxTag) {
   11720                 @Override
   11721                 public void run() {
   11722                     String report;
   11723                     synchronized (sb) {
   11724                         report = sb.toString();
   11725                         sb.delete(0, sb.length());
   11726                         sb.trimToSize();
   11727                     }
   11728                     if (report.length() != 0) {
   11729                         dbox.addText(dropboxTag, report);
   11730                     }
   11731                 }
   11732             }.start();
   11733             return;
   11734         }
   11735 
   11736         // System app batching:
   11737         if (!bufferWasEmpty) {
   11738             // An existing dropbox-writing thread is outstanding, so
   11739             // we don't need to start it up.  The existing thread will
   11740             // catch the buffer appends we just did.
   11741             return;
   11742         }
   11743 
   11744         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   11745         // (After this point, we shouldn't access AMS internal data structures.)
   11746         new Thread("Error dump: " + dropboxTag) {
   11747             @Override
   11748             public void run() {
   11749                 // 5 second sleep to let stacks arrive and be batched together
   11750                 try {
   11751                     Thread.sleep(5000);  // 5 seconds
   11752                 } catch (InterruptedException e) {}
   11753 
   11754                 String errorReport;
   11755                 synchronized (mStrictModeBuffer) {
   11756                     errorReport = mStrictModeBuffer.toString();
   11757                     if (errorReport.length() == 0) {
   11758                         return;
   11759                     }
   11760                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   11761                     mStrictModeBuffer.trimToSize();
   11762                 }
   11763                 dbox.addText(dropboxTag, errorReport);
   11764             }
   11765         }.start();
   11766     }
   11767 
   11768     /**
   11769      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   11770      * @param app object of the crashing app, null for the system server
   11771      * @param tag reported by the caller
   11772      * @param system whether this wtf is coming from the system
   11773      * @param crashInfo describing the context of the error
   11774      * @return true if the process should exit immediately (WTF is fatal)
   11775      */
   11776     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   11777             final ApplicationErrorReport.CrashInfo crashInfo) {
   11778         final int callingUid = Binder.getCallingUid();
   11779         final int callingPid = Binder.getCallingPid();
   11780 
   11781         if (system) {
   11782             // If this is coming from the system, we could very well have low-level
   11783             // system locks held, so we want to do this all asynchronously.  And we
   11784             // never want this to become fatal, so there is that too.
   11785             mHandler.post(new Runnable() {
   11786                 @Override public void run() {
   11787                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   11788                 }
   11789             });
   11790             return false;
   11791         }
   11792 
   11793         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   11794                 crashInfo);
   11795 
   11796         if (r != null && r.pid != Process.myPid() &&
   11797                 Settings.Global.getInt(mContext.getContentResolver(),
   11798                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   11799             crashApplication(r, crashInfo);
   11800             return true;
   11801         } else {
   11802             return false;
   11803         }
   11804     }
   11805 
   11806     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   11807             final ApplicationErrorReport.CrashInfo crashInfo) {
   11808         final ProcessRecord r = findAppProcess(app, "WTF");
   11809         final String processName = app == null ? "system_server"
   11810                 : (r == null ? "unknown" : r.processName);
   11811 
   11812         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   11813                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   11814 
   11815         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   11816 
   11817         return r;
   11818     }
   11819 
   11820     /**
   11821      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   11822      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   11823      */
   11824     private ProcessRecord findAppProcess(IBinder app, String reason) {
   11825         if (app == null) {
   11826             return null;
   11827         }
   11828 
   11829         synchronized (this) {
   11830             final int NP = mProcessNames.getMap().size();
   11831             for (int ip=0; ip<NP; ip++) {
   11832                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11833                 final int NA = apps.size();
   11834                 for (int ia=0; ia<NA; ia++) {
   11835                     ProcessRecord p = apps.valueAt(ia);
   11836                     if (p.thread != null && p.thread.asBinder() == app) {
   11837                         return p;
   11838                     }
   11839                 }
   11840             }
   11841 
   11842             Slog.w(TAG, "Can't find mystery application for " + reason
   11843                     + " from pid=" + Binder.getCallingPid()
   11844                     + " uid=" + Binder.getCallingUid() + ": " + app);
   11845             return null;
   11846         }
   11847     }
   11848 
   11849     /**
   11850      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   11851      * to append various headers to the dropbox log text.
   11852      */
   11853     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   11854             StringBuilder sb) {
   11855         // Watchdog thread ends up invoking this function (with
   11856         // a null ProcessRecord) to add the stack file to dropbox.
   11857         // Do not acquire a lock on this (am) in such cases, as it
   11858         // could cause a potential deadlock, if and when watchdog
   11859         // is invoked due to unavailability of lock on am and it
   11860         // would prevent watchdog from killing system_server.
   11861         if (process == null) {
   11862             sb.append("Process: ").append(processName).append("\n");
   11863             return;
   11864         }
   11865         // Note: ProcessRecord 'process' is guarded by the service
   11866         // instance.  (notably process.pkgList, which could otherwise change
   11867         // concurrently during execution of this method)
   11868         synchronized (this) {
   11869             sb.append("Process: ").append(processName).append("\n");
   11870             int flags = process.info.flags;
   11871             IPackageManager pm = AppGlobals.getPackageManager();
   11872             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   11873             for (int ip=0; ip<process.pkgList.size(); ip++) {
   11874                 String pkg = process.pkgList.keyAt(ip);
   11875                 sb.append("Package: ").append(pkg);
   11876                 try {
   11877                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   11878                     if (pi != null) {
   11879                         sb.append(" v").append(pi.versionCode);
   11880                         if (pi.versionName != null) {
   11881                             sb.append(" (").append(pi.versionName).append(")");
   11882                         }
   11883                     }
   11884                 } catch (RemoteException e) {
   11885                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   11886                 }
   11887                 sb.append("\n");
   11888             }
   11889         }
   11890     }
   11891 
   11892     private static String processClass(ProcessRecord process) {
   11893         if (process == null || process.pid == MY_PID) {
   11894             return "system_server";
   11895         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   11896             return "system_app";
   11897         } else {
   11898             return "data_app";
   11899         }
   11900     }
   11901 
   11902     /**
   11903      * Write a description of an error (crash, WTF, ANR) to the drop box.
   11904      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   11905      * @param process which caused the error, null means the system server
   11906      * @param activity which triggered the error, null if unknown
   11907      * @param parent activity related to the error, null if unknown
   11908      * @param subject line related to the error, null if absent
   11909      * @param report in long form describing the error, null if absent
   11910      * @param logFile to include in the report, null if none
   11911      * @param crashInfo giving an application stack trace, null if absent
   11912      */
   11913     public void addErrorToDropBox(String eventType,
   11914             ProcessRecord process, String processName, ActivityRecord activity,
   11915             ActivityRecord parent, String subject,
   11916             final String report, final File logFile,
   11917             final ApplicationErrorReport.CrashInfo crashInfo) {
   11918         // NOTE -- this must never acquire the ActivityManagerService lock,
   11919         // otherwise the watchdog may be prevented from resetting the system.
   11920 
   11921         final String dropboxTag = processClass(process) + "_" + eventType;
   11922         final DropBoxManager dbox = (DropBoxManager)
   11923                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11924 
   11925         // Exit early if the dropbox isn't configured to accept this report type.
   11926         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11927 
   11928         final StringBuilder sb = new StringBuilder(1024);
   11929         appendDropBoxProcessHeaders(process, processName, sb);
   11930         if (activity != null) {
   11931             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   11932         }
   11933         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   11934             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   11935         }
   11936         if (parent != null && parent != activity) {
   11937             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   11938         }
   11939         if (subject != null) {
   11940             sb.append("Subject: ").append(subject).append("\n");
   11941         }
   11942         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11943         if (Debug.isDebuggerConnected()) {
   11944             sb.append("Debugger: Connected\n");
   11945         }
   11946         sb.append("\n");
   11947 
   11948         // Do the rest in a worker thread to avoid blocking the caller on I/O
   11949         // (After this point, we shouldn't access AMS internal data structures.)
   11950         Thread worker = new Thread("Error dump: " + dropboxTag) {
   11951             @Override
   11952             public void run() {
   11953                 if (report != null) {
   11954                     sb.append(report);
   11955                 }
   11956                 if (logFile != null) {
   11957                     try {
   11958                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
   11959                                     "\n\n[[TRUNCATED]]"));
   11960                     } catch (IOException e) {
   11961                         Slog.e(TAG, "Error reading " + logFile, e);
   11962                     }
   11963                 }
   11964                 if (crashInfo != null && crashInfo.stackTrace != null) {
   11965                     sb.append(crashInfo.stackTrace);
   11966                 }
   11967 
   11968                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   11969                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   11970                 if (lines > 0) {
   11971                     sb.append("\n");
   11972 
   11973                     // Merge several logcat streams, and take the last N lines
   11974                     InputStreamReader input = null;
   11975                     try {
   11976                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   11977                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   11978                                 "-b", "crash",
   11979                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   11980 
   11981                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   11982                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   11983                         input = new InputStreamReader(logcat.getInputStream());
   11984 
   11985                         int num;
   11986                         char[] buf = new char[8192];
   11987                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   11988                     } catch (IOException e) {
   11989                         Slog.e(TAG, "Error running logcat", e);
   11990                     } finally {
   11991                         if (input != null) try { input.close(); } catch (IOException e) {}
   11992                     }
   11993                 }
   11994 
   11995                 dbox.addText(dropboxTag, sb.toString());
   11996             }
   11997         };
   11998 
   11999         if (process == null) {
   12000             // If process is null, we are being called from some internal code
   12001             // and may be about to die -- run this synchronously.
   12002             worker.run();
   12003         } else {
   12004             worker.start();
   12005         }
   12006     }
   12007 
   12008     /**
   12009      * Bring up the "unexpected error" dialog box for a crashing app.
   12010      * Deal with edge cases (intercepts from instrumented applications,
   12011      * ActivityController, error intent receivers, that sort of thing).
   12012      * @param r the application crashing
   12013      * @param crashInfo describing the failure
   12014      */
   12015     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   12016         long timeMillis = System.currentTimeMillis();
   12017         String shortMsg = crashInfo.exceptionClassName;
   12018         String longMsg = crashInfo.exceptionMessage;
   12019         String stackTrace = crashInfo.stackTrace;
   12020         if (shortMsg != null && longMsg != null) {
   12021             longMsg = shortMsg + ": " + longMsg;
   12022         } else if (shortMsg != null) {
   12023             longMsg = shortMsg;
   12024         }
   12025 
   12026         AppErrorResult result = new AppErrorResult();
   12027         synchronized (this) {
   12028             if (mController != null) {
   12029                 try {
   12030                     String name = r != null ? r.processName : null;
   12031                     int pid = r != null ? r.pid : Binder.getCallingPid();
   12032                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
   12033                     if (!mController.appCrashed(name, pid,
   12034                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   12035                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
   12036                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
   12037                             Slog.w(TAG, "Skip killing native crashed app " + name
   12038                                     + "(" + pid + ") during testing");
   12039                         } else {
   12040                             Slog.w(TAG, "Force-killing crashed app " + name
   12041                                     + " at watcher's request");
   12042                             if (r != null) {
   12043                                 r.kill("crash", true);
   12044                             } else {
   12045                                 // Huh.
   12046                                 Process.killProcess(pid);
   12047                                 Process.killProcessGroup(uid, pid);
   12048                             }
   12049                         }
   12050                         return;
   12051                     }
   12052                 } catch (RemoteException e) {
   12053                     mController = null;
   12054                     Watchdog.getInstance().setActivityController(null);
   12055                 }
   12056             }
   12057 
   12058             final long origId = Binder.clearCallingIdentity();
   12059 
   12060             // If this process is running instrumentation, finish it.
   12061             if (r != null && r.instrumentationClass != null) {
   12062                 Slog.w(TAG, "Error in app " + r.processName
   12063                       + " running instrumentation " + r.instrumentationClass + ":");
   12064                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   12065                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   12066                 Bundle info = new Bundle();
   12067                 info.putString("shortMsg", shortMsg);
   12068                 info.putString("longMsg", longMsg);
   12069                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   12070                 Binder.restoreCallingIdentity(origId);
   12071                 return;
   12072             }
   12073 
   12074             // Log crash in battery stats.
   12075             if (r != null) {
   12076                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
   12077             }
   12078 
   12079             // If we can't identify the process or it's already exceeded its crash quota,
   12080             // quit right away without showing a crash dialog.
   12081             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   12082                 Binder.restoreCallingIdentity(origId);
   12083                 return;
   12084             }
   12085 
   12086             Message msg = Message.obtain();
   12087             msg.what = SHOW_ERROR_MSG;
   12088             HashMap data = new HashMap();
   12089             data.put("result", result);
   12090             data.put("app", r);
   12091             msg.obj = data;
   12092             mHandler.sendMessage(msg);
   12093 
   12094             Binder.restoreCallingIdentity(origId);
   12095         }
   12096 
   12097         int res = result.get();
   12098 
   12099         Intent appErrorIntent = null;
   12100         synchronized (this) {
   12101             if (r != null && !r.isolated) {
   12102                 // XXX Can't keep track of crash time for isolated processes,
   12103                 // since they don't have a persistent identity.
   12104                 mProcessCrashTimes.put(r.info.processName, r.uid,
   12105                         SystemClock.uptimeMillis());
   12106             }
   12107             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   12108                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   12109             }
   12110         }
   12111 
   12112         if (appErrorIntent != null) {
   12113             try {
   12114                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   12115             } catch (ActivityNotFoundException e) {
   12116                 Slog.w(TAG, "bug report receiver dissappeared", e);
   12117             }
   12118         }
   12119     }
   12120 
   12121     Intent createAppErrorIntentLocked(ProcessRecord r,
   12122             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12123         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   12124         if (report == null) {
   12125             return null;
   12126         }
   12127         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   12128         result.setComponent(r.errorReportReceiver);
   12129         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   12130         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   12131         return result;
   12132     }
   12133 
   12134     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   12135             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12136         if (r.errorReportReceiver == null) {
   12137             return null;
   12138         }
   12139 
   12140         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   12141             return null;
   12142         }
   12143 
   12144         ApplicationErrorReport report = new ApplicationErrorReport();
   12145         report.packageName = r.info.packageName;
   12146         report.installerPackageName = r.errorReportReceiver.getPackageName();
   12147         report.processName = r.processName;
   12148         report.time = timeMillis;
   12149         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   12150 
   12151         if (r.crashing || r.forceCrashReport) {
   12152             report.type = ApplicationErrorReport.TYPE_CRASH;
   12153             report.crashInfo = crashInfo;
   12154         } else if (r.notResponding) {
   12155             report.type = ApplicationErrorReport.TYPE_ANR;
   12156             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   12157 
   12158             report.anrInfo.activity = r.notRespondingReport.tag;
   12159             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   12160             report.anrInfo.info = r.notRespondingReport.longMsg;
   12161         }
   12162 
   12163         return report;
   12164     }
   12165 
   12166     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   12167         enforceNotIsolatedCaller("getProcessesInErrorState");
   12168         // assume our apps are happy - lazy create the list
   12169         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   12170 
   12171         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12172                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   12173         int userId = UserHandle.getUserId(Binder.getCallingUid());
   12174 
   12175         synchronized (this) {
   12176 
   12177             // iterate across all processes
   12178             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12179                 ProcessRecord app = mLruProcesses.get(i);
   12180                 if (!allUsers && app.userId != userId) {
   12181                     continue;
   12182                 }
   12183                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   12184                     // This one's in trouble, so we'll generate a report for it
   12185                     // crashes are higher priority (in case there's a crash *and* an anr)
   12186                     ActivityManager.ProcessErrorStateInfo report = null;
   12187                     if (app.crashing) {
   12188                         report = app.crashingReport;
   12189                     } else if (app.notResponding) {
   12190                         report = app.notRespondingReport;
   12191                     }
   12192 
   12193                     if (report != null) {
   12194                         if (errList == null) {
   12195                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   12196                         }
   12197                         errList.add(report);
   12198                     } else {
   12199                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   12200                                 " crashing = " + app.crashing +
   12201                                 " notResponding = " + app.notResponding);
   12202                     }
   12203                 }
   12204             }
   12205         }
   12206 
   12207         return errList;
   12208     }
   12209 
   12210     static int procStateToImportance(int procState, int memAdj,
   12211             ActivityManager.RunningAppProcessInfo currApp) {
   12212         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   12213         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   12214             currApp.lru = memAdj;
   12215         } else {
   12216             currApp.lru = 0;
   12217         }
   12218         return imp;
   12219     }
   12220 
   12221     private void fillInProcMemInfo(ProcessRecord app,
   12222             ActivityManager.RunningAppProcessInfo outInfo) {
   12223         outInfo.pid = app.pid;
   12224         outInfo.uid = app.info.uid;
   12225         if (mHeavyWeightProcess == app) {
   12226             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   12227         }
   12228         if (app.persistent) {
   12229             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   12230         }
   12231         if (app.activities.size() > 0) {
   12232             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   12233         }
   12234         outInfo.lastTrimLevel = app.trimMemoryLevel;
   12235         int adj = app.curAdj;
   12236         int procState = app.curProcState;
   12237         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   12238         outInfo.importanceReasonCode = app.adjTypeCode;
   12239         outInfo.processState = app.curProcState;
   12240     }
   12241 
   12242     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   12243         enforceNotIsolatedCaller("getRunningAppProcesses");
   12244         // Lazy instantiation of list
   12245         List<ActivityManager.RunningAppProcessInfo> runList = null;
   12246         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12247                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   12248         int userId = UserHandle.getUserId(Binder.getCallingUid());
   12249         synchronized (this) {
   12250             // Iterate across all processes
   12251             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12252                 ProcessRecord app = mLruProcesses.get(i);
   12253                 if (!allUsers && app.userId != userId) {
   12254                     continue;
   12255                 }
   12256                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   12257                     // Generate process state info for running application
   12258                     ActivityManager.RunningAppProcessInfo currApp =
   12259                         new ActivityManager.RunningAppProcessInfo(app.processName,
   12260                                 app.pid, app.getPackageList());
   12261                     fillInProcMemInfo(app, currApp);
   12262                     if (app.adjSource instanceof ProcessRecord) {
   12263                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   12264                         currApp.importanceReasonImportance =
   12265                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   12266                                         app.adjSourceProcState);
   12267                     } else if (app.adjSource instanceof ActivityRecord) {
   12268                         ActivityRecord r = (ActivityRecord)app.adjSource;
   12269                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   12270                     }
   12271                     if (app.adjTarget instanceof ComponentName) {
   12272                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   12273                     }
   12274                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   12275                     //        + " lru=" + currApp.lru);
   12276                     if (runList == null) {
   12277                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   12278                     }
   12279                     runList.add(currApp);
   12280                 }
   12281             }
   12282         }
   12283         return runList;
   12284     }
   12285 
   12286     public List<ApplicationInfo> getRunningExternalApplications() {
   12287         enforceNotIsolatedCaller("getRunningExternalApplications");
   12288         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   12289         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   12290         if (runningApps != null && runningApps.size() > 0) {
   12291             Set<String> extList = new HashSet<String>();
   12292             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   12293                 if (app.pkgList != null) {
   12294                     for (String pkg : app.pkgList) {
   12295                         extList.add(pkg);
   12296                     }
   12297                 }
   12298             }
   12299             IPackageManager pm = AppGlobals.getPackageManager();
   12300             for (String pkg : extList) {
   12301                 try {
   12302                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   12303                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   12304                         retList.add(info);
   12305                     }
   12306                 } catch (RemoteException e) {
   12307                 }
   12308             }
   12309         }
   12310         return retList;
   12311     }
   12312 
   12313     @Override
   12314     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   12315         enforceNotIsolatedCaller("getMyMemoryState");
   12316         synchronized (this) {
   12317             ProcessRecord proc;
   12318             synchronized (mPidsSelfLocked) {
   12319                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   12320             }
   12321             fillInProcMemInfo(proc, outInfo);
   12322         }
   12323     }
   12324 
   12325     @Override
   12326     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   12327         if (checkCallingPermission(android.Manifest.permission.DUMP)
   12328                 != PackageManager.PERMISSION_GRANTED) {
   12329             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   12330                     + Binder.getCallingPid()
   12331                     + ", uid=" + Binder.getCallingUid()
   12332                     + " without permission "
   12333                     + android.Manifest.permission.DUMP);
   12334             return;
   12335         }
   12336 
   12337         boolean dumpAll = false;
   12338         boolean dumpClient = false;
   12339         String dumpPackage = null;
   12340 
   12341         int opti = 0;
   12342         while (opti < args.length) {
   12343             String opt = args[opti];
   12344             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   12345                 break;
   12346             }
   12347             opti++;
   12348             if ("-a".equals(opt)) {
   12349                 dumpAll = true;
   12350             } else if ("-c".equals(opt)) {
   12351                 dumpClient = true;
   12352             } else if ("-p".equals(opt)) {
   12353                 if (opti < args.length) {
   12354                     dumpPackage = args[opti];
   12355                     opti++;
   12356                 } else {
   12357                     pw.println("Error: -p option requires package argument");
   12358                     return;
   12359                 }
   12360                 dumpClient = true;
   12361             } else if ("-h".equals(opt)) {
   12362                 pw.println("Activity manager dump options:");
   12363                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
   12364                 pw.println("  cmd may be one of:");
   12365                 pw.println("    a[ctivities]: activity stack state");
   12366                 pw.println("    r[recents]: recent activities state");
   12367                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   12368                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   12369                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   12370                 pw.println("    o[om]: out of memory management");
   12371                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   12372                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   12373                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   12374                 pw.println("    as[sociations]: tracked app associations");
   12375                 pw.println("    service [COMP_SPEC]: service client-side state");
   12376                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   12377                 pw.println("    all: dump all activities");
   12378                 pw.println("    top: dump the top activity");
   12379                 pw.println("    write: write all pending state to storage");
   12380                 pw.println("    track-associations: enable association tracking");
   12381                 pw.println("    untrack-associations: disable and clear association tracking");
   12382                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   12383                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   12384                 pw.println("    a partial substring in a component name, a");
   12385                 pw.println("    hex object identifier.");
   12386                 pw.println("  -a: include all available server state.");
   12387                 pw.println("  -c: include client state.");
   12388                 pw.println("  -p: limit output to given package.");
   12389                 return;
   12390             } else {
   12391                 pw.println("Unknown argument: " + opt + "; use -h for help");
   12392             }
   12393         }
   12394 
   12395         long origId = Binder.clearCallingIdentity();
   12396         boolean more = false;
   12397         // Is the caller requesting to dump a particular piece of data?
   12398         if (opti < args.length) {
   12399             String cmd = args[opti];
   12400             opti++;
   12401             if ("activities".equals(cmd) || "a".equals(cmd)) {
   12402                 synchronized (this) {
   12403                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12404                 }
   12405             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   12406                 synchronized (this) {
   12407                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
   12408                 }
   12409             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   12410                 String[] newArgs;
   12411                 String name;
   12412                 if (opti >= args.length) {
   12413                     name = null;
   12414                     newArgs = EMPTY_STRING_ARRAY;
   12415                 } else {
   12416                     dumpPackage = args[opti];
   12417                     opti++;
   12418                     newArgs = new String[args.length - opti];
   12419                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12420                             args.length - opti);
   12421                 }
   12422                 synchronized (this) {
   12423                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
   12424                 }
   12425             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   12426                 String[] newArgs;
   12427                 String name;
   12428                 if (opti >= args.length) {
   12429                     name = null;
   12430                     newArgs = EMPTY_STRING_ARRAY;
   12431                 } else {
   12432                     dumpPackage = args[opti];
   12433                     opti++;
   12434                     newArgs = new String[args.length - opti];
   12435                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12436                             args.length - opti);
   12437                 }
   12438                 synchronized (this) {
   12439                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
   12440                 }
   12441             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   12442                 String[] newArgs;
   12443                 String name;
   12444                 if (opti >= args.length) {
   12445                     name = null;
   12446                     newArgs = EMPTY_STRING_ARRAY;
   12447                 } else {
   12448                     dumpPackage = args[opti];
   12449                     opti++;
   12450                     newArgs = new String[args.length - opti];
   12451                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12452                             args.length - opti);
   12453                 }
   12454                 synchronized (this) {
   12455                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
   12456                 }
   12457             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   12458                 synchronized (this) {
   12459                     dumpOomLocked(fd, pw, args, opti, true);
   12460                 }
   12461             } else if ("provider".equals(cmd)) {
   12462                 String[] newArgs;
   12463                 String name;
   12464                 if (opti >= args.length) {
   12465                     name = null;
   12466                     newArgs = EMPTY_STRING_ARRAY;
   12467                 } else {
   12468                     name = args[opti];
   12469                     opti++;
   12470                     newArgs = new String[args.length - opti];
   12471                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   12472                 }
   12473                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   12474                     pw.println("No providers match: " + name);
   12475                     pw.println("Use -h for help.");
   12476                 }
   12477             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   12478                 synchronized (this) {
   12479                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   12480                 }
   12481             } else if ("service".equals(cmd)) {
   12482                 String[] newArgs;
   12483                 String name;
   12484                 if (opti >= args.length) {
   12485                     name = null;
   12486                     newArgs = EMPTY_STRING_ARRAY;
   12487                 } else {
   12488                     name = args[opti];
   12489                     opti++;
   12490                     newArgs = new String[args.length - opti];
   12491                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12492                             args.length - opti);
   12493                 }
   12494                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   12495                     pw.println("No services match: " + name);
   12496                     pw.println("Use -h for help.");
   12497                 }
   12498             } else if ("package".equals(cmd)) {
   12499                 String[] newArgs;
   12500                 if (opti >= args.length) {
   12501                     pw.println("package: no package name specified");
   12502                     pw.println("Use -h for help.");
   12503                 } else {
   12504                     dumpPackage = args[opti];
   12505                     opti++;
   12506                     newArgs = new String[args.length - opti];
   12507                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12508                             args.length - opti);
   12509                     args = newArgs;
   12510                     opti = 0;
   12511                     more = true;
   12512                 }
   12513             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
   12514                 synchronized (this) {
   12515                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12516                 }
   12517             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   12518                 synchronized (this) {
   12519                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
   12520                 }
   12521             } else if ("write".equals(cmd)) {
   12522                 mTaskPersister.flush();
   12523                 pw.println("All tasks persisted.");
   12524                 return;
   12525             } else if ("track-associations".equals(cmd)) {
   12526                 synchronized (this) {
   12527                     if (!mTrackingAssociations) {
   12528                         mTrackingAssociations = true;
   12529                         pw.println("Association tracking started.");
   12530                     } else {
   12531                         pw.println("Association tracking already enabled.");
   12532                     }
   12533                 }
   12534                 return;
   12535             } else if ("untrack-associations".equals(cmd)) {
   12536                 synchronized (this) {
   12537                     if (mTrackingAssociations) {
   12538                         mTrackingAssociations = false;
   12539                         mAssociations.clear();
   12540                         pw.println("Association tracking stopped.");
   12541                     } else {
   12542                         pw.println("Association tracking not running.");
   12543                     }
   12544                 }
   12545                 return;
   12546             } else {
   12547                 // Dumping a single activity?
   12548                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   12549                     pw.println("Bad activity command, or no activities match: " + cmd);
   12550                     pw.println("Use -h for help.");
   12551                 }
   12552             }
   12553             if (!more) {
   12554                 Binder.restoreCallingIdentity(origId);
   12555                 return;
   12556             }
   12557         }
   12558 
   12559         // No piece of data specified, dump everything.
   12560         synchronized (this) {
   12561             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12562             pw.println();
   12563             if (dumpAll) {
   12564                 pw.println("-------------------------------------------------------------------------------");
   12565             }
   12566             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12567             pw.println();
   12568             if (dumpAll) {
   12569                 pw.println("-------------------------------------------------------------------------------");
   12570             }
   12571             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12572             pw.println();
   12573             if (dumpAll) {
   12574                 pw.println("-------------------------------------------------------------------------------");
   12575             }
   12576             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12577             pw.println();
   12578             if (dumpAll) {
   12579                 pw.println("-------------------------------------------------------------------------------");
   12580             }
   12581             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12582             pw.println();
   12583             if (dumpAll) {
   12584                 pw.println("-------------------------------------------------------------------------------");
   12585             }
   12586             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12587             if (mAssociations.size() > 0) {
   12588                 pw.println();
   12589                 if (dumpAll) {
   12590                     pw.println("-------------------------------------------------------------------------------");
   12591                 }
   12592                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12593             }
   12594             pw.println();
   12595             if (dumpAll) {
   12596                 pw.println("-------------------------------------------------------------------------------");
   12597             }
   12598             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12599         }
   12600         Binder.restoreCallingIdentity(origId);
   12601     }
   12602 
   12603     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12604             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   12605         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   12606 
   12607         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   12608                 dumpPackage);
   12609         boolean needSep = printedAnything;
   12610 
   12611         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   12612                 dumpPackage, needSep, "  mFocusedActivity: ");
   12613         if (printed) {
   12614             printedAnything = true;
   12615             needSep = false;
   12616         }
   12617 
   12618         if (dumpPackage == null) {
   12619             if (needSep) {
   12620                 pw.println();
   12621             }
   12622             needSep = true;
   12623             printedAnything = true;
   12624             mStackSupervisor.dump(pw, "  ");
   12625         }
   12626 
   12627         if (!printedAnything) {
   12628             pw.println("  (nothing)");
   12629         }
   12630     }
   12631 
   12632     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12633             int opti, boolean dumpAll, String dumpPackage) {
   12634         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   12635 
   12636         boolean printedAnything = false;
   12637 
   12638         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   12639             boolean printedHeader = false;
   12640 
   12641             final int N = mRecentTasks.size();
   12642             for (int i=0; i<N; i++) {
   12643                 TaskRecord tr = mRecentTasks.get(i);
   12644                 if (dumpPackage != null) {
   12645                     if (tr.realActivity == null ||
   12646                             !dumpPackage.equals(tr.realActivity)) {
   12647                         continue;
   12648                     }
   12649                 }
   12650                 if (!printedHeader) {
   12651                     pw.println("  Recent tasks:");
   12652                     printedHeader = true;
   12653                     printedAnything = true;
   12654                 }
   12655                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   12656                         pw.println(tr);
   12657                 if (dumpAll) {
   12658                     mRecentTasks.get(i).dump(pw, "    ");
   12659                 }
   12660             }
   12661         }
   12662 
   12663         if (!printedAnything) {
   12664             pw.println("  (nothing)");
   12665         }
   12666     }
   12667 
   12668     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12669             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   12670         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
   12671 
   12672         int dumpUid = 0;
   12673         if (dumpPackage != null) {
   12674             IPackageManager pm = AppGlobals.getPackageManager();
   12675             try {
   12676                 dumpUid = pm.getPackageUid(dumpPackage, 0);
   12677             } catch (RemoteException e) {
   12678             }
   12679         }
   12680 
   12681         boolean printedAnything = false;
   12682 
   12683         final long now = SystemClock.uptimeMillis();
   12684 
   12685         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
   12686             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
   12687                     = mAssociations.valueAt(i1);
   12688             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
   12689                 SparseArray<ArrayMap<String, Association>> sourceUids
   12690                         = targetComponents.valueAt(i2);
   12691                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
   12692                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
   12693                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
   12694                         Association ass = sourceProcesses.valueAt(i4);
   12695                         if (dumpPackage != null) {
   12696                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
   12697                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
   12698                                 continue;
   12699                             }
   12700                         }
   12701                         printedAnything = true;
   12702                         pw.print("  ");
   12703                         pw.print(ass.mTargetProcess);
   12704                         pw.print("/");
   12705                         UserHandle.formatUid(pw, ass.mTargetUid);
   12706                         pw.print(" <- ");
   12707                         pw.print(ass.mSourceProcess);
   12708                         pw.print("/");
   12709                         UserHandle.formatUid(pw, ass.mSourceUid);
   12710                         pw.println();
   12711                         pw.print("    via ");
   12712                         pw.print(ass.mTargetComponent.flattenToShortString());
   12713                         pw.println();
   12714                         pw.print("    ");
   12715                         long dur = ass.mTime;
   12716                         if (ass.mNesting > 0) {
   12717                             dur += now - ass.mStartTime;
   12718                         }
   12719                         TimeUtils.formatDuration(dur, pw);
   12720                         pw.print(" (");
   12721                         pw.print(ass.mCount);
   12722                         pw.println(" times)");
   12723                         if (ass.mNesting > 0) {
   12724                             pw.print("    ");
   12725                             pw.print(" Currently active: ");
   12726                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
   12727                             pw.println();
   12728                         }
   12729                     }
   12730                 }
   12731             }
   12732 
   12733         }
   12734 
   12735         if (!printedAnything) {
   12736             pw.println("  (nothing)");
   12737         }
   12738     }
   12739 
   12740     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12741             int opti, boolean dumpAll, String dumpPackage) {
   12742         boolean needSep = false;
   12743         boolean printedAnything = false;
   12744         int numPers = 0;
   12745 
   12746         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   12747 
   12748         if (dumpAll) {
   12749             final int NP = mProcessNames.getMap().size();
   12750             for (int ip=0; ip<NP; ip++) {
   12751                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   12752                 final int NA = procs.size();
   12753                 for (int ia=0; ia<NA; ia++) {
   12754                     ProcessRecord r = procs.valueAt(ia);
   12755                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12756                         continue;
   12757                     }
   12758                     if (!needSep) {
   12759                         pw.println("  All known processes:");
   12760                         needSep = true;
   12761                         printedAnything = true;
   12762                     }
   12763                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   12764                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   12765                         pw.print(" "); pw.println(r);
   12766                     r.dump(pw, "    ");
   12767                     if (r.persistent) {
   12768                         numPers++;
   12769                     }
   12770                 }
   12771             }
   12772         }
   12773 
   12774         if (mIsolatedProcesses.size() > 0) {
   12775             boolean printed = false;
   12776             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   12777                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   12778                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12779                     continue;
   12780                 }
   12781                 if (!printed) {
   12782                     if (needSep) {
   12783                         pw.println();
   12784                     }
   12785                     pw.println("  Isolated process list (sorted by uid):");
   12786                     printedAnything = true;
   12787                     printed = true;
   12788                     needSep = true;
   12789                 }
   12790                 pw.println(String.format("%sIsolated #%2d: %s",
   12791                         "    ", i, r.toString()));
   12792             }
   12793         }
   12794 
   12795         if (mLruProcesses.size() > 0) {
   12796             if (needSep) {
   12797                 pw.println();
   12798             }
   12799             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   12800                     pw.print(" total, non-act at ");
   12801                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   12802                     pw.print(", non-svc at ");
   12803                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   12804                     pw.println("):");
   12805             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   12806             needSep = true;
   12807             printedAnything = true;
   12808         }
   12809 
   12810         if (dumpAll || dumpPackage != null) {
   12811             synchronized (mPidsSelfLocked) {
   12812                 boolean printed = false;
   12813                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   12814                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   12815                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12816                         continue;
   12817                     }
   12818                     if (!printed) {
   12819                         if (needSep) pw.println();
   12820                         needSep = true;
   12821                         pw.println("  PID mappings:");
   12822                         printed = true;
   12823                         printedAnything = true;
   12824                     }
   12825                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   12826                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   12827                 }
   12828             }
   12829         }
   12830 
   12831         if (mForegroundProcesses.size() > 0) {
   12832             synchronized (mPidsSelfLocked) {
   12833                 boolean printed = false;
   12834                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   12835                     ProcessRecord r = mPidsSelfLocked.get(
   12836                             mForegroundProcesses.valueAt(i).pid);
   12837                     if (dumpPackage != null && (r == null
   12838                             || !r.pkgList.containsKey(dumpPackage))) {
   12839                         continue;
   12840                     }
   12841                     if (!printed) {
   12842                         if (needSep) pw.println();
   12843                         needSep = true;
   12844                         pw.println("  Foreground Processes:");
   12845                         printed = true;
   12846                         printedAnything = true;
   12847                     }
   12848                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   12849                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   12850                 }
   12851             }
   12852         }
   12853 
   12854         if (mPersistentStartingProcesses.size() > 0) {
   12855             if (needSep) pw.println();
   12856             needSep = true;
   12857             printedAnything = true;
   12858             pw.println("  Persisent processes that are starting:");
   12859             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   12860                     "Starting Norm", "Restarting PERS", dumpPackage);
   12861         }
   12862 
   12863         if (mRemovedProcesses.size() > 0) {
   12864             if (needSep) pw.println();
   12865             needSep = true;
   12866             printedAnything = true;
   12867             pw.println("  Processes that are being removed:");
   12868             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   12869                     "Removed Norm", "Removed PERS", dumpPackage);
   12870         }
   12871 
   12872         if (mProcessesOnHold.size() > 0) {
   12873             if (needSep) pw.println();
   12874             needSep = true;
   12875             printedAnything = true;
   12876             pw.println("  Processes that are on old until the system is ready:");
   12877             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   12878                     "OnHold Norm", "OnHold PERS", dumpPackage);
   12879         }
   12880 
   12881         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   12882 
   12883         if (mProcessCrashTimes.getMap().size() > 0) {
   12884             boolean printed = false;
   12885             long now = SystemClock.uptimeMillis();
   12886             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   12887             final int NP = pmap.size();
   12888             for (int ip=0; ip<NP; ip++) {
   12889                 String pname = pmap.keyAt(ip);
   12890                 SparseArray<Long> uids = pmap.valueAt(ip);
   12891                 final int N = uids.size();
   12892                 for (int i=0; i<N; i++) {
   12893                     int puid = uids.keyAt(i);
   12894                     ProcessRecord r = mProcessNames.get(pname, puid);
   12895                     if (dumpPackage != null && (r == null
   12896                             || !r.pkgList.containsKey(dumpPackage))) {
   12897                         continue;
   12898                     }
   12899                     if (!printed) {
   12900                         if (needSep) pw.println();
   12901                         needSep = true;
   12902                         pw.println("  Time since processes crashed:");
   12903                         printed = true;
   12904                         printedAnything = true;
   12905                     }
   12906                     pw.print("    Process "); pw.print(pname);
   12907                             pw.print(" uid "); pw.print(puid);
   12908                             pw.print(": last crashed ");
   12909                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   12910                             pw.println(" ago");
   12911                 }
   12912             }
   12913         }
   12914 
   12915         if (mBadProcesses.getMap().size() > 0) {
   12916             boolean printed = false;
   12917             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
   12918             final int NP = pmap.size();
   12919             for (int ip=0; ip<NP; ip++) {
   12920                 String pname = pmap.keyAt(ip);
   12921                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
   12922                 final int N = uids.size();
   12923                 for (int i=0; i<N; i++) {
   12924                     int puid = uids.keyAt(i);
   12925                     ProcessRecord r = mProcessNames.get(pname, puid);
   12926                     if (dumpPackage != null && (r == null
   12927                             || !r.pkgList.containsKey(dumpPackage))) {
   12928                         continue;
   12929                     }
   12930                     if (!printed) {
   12931                         if (needSep) pw.println();
   12932                         needSep = true;
   12933                         pw.println("  Bad processes:");
   12934                         printedAnything = true;
   12935                     }
   12936                     BadProcessInfo info = uids.valueAt(i);
   12937                     pw.print("    Bad process "); pw.print(pname);
   12938                             pw.print(" uid "); pw.print(puid);
   12939                             pw.print(": crashed at time "); pw.println(info.time);
   12940                     if (info.shortMsg != null) {
   12941                         pw.print("      Short msg: "); pw.println(info.shortMsg);
   12942                     }
   12943                     if (info.longMsg != null) {
   12944                         pw.print("      Long msg: "); pw.println(info.longMsg);
   12945                     }
   12946                     if (info.stack != null) {
   12947                         pw.println("      Stack:");
   12948                         int lastPos = 0;
   12949                         for (int pos=0; pos<info.stack.length(); pos++) {
   12950                             if (info.stack.charAt(pos) == '\n') {
   12951                                 pw.print("        ");
   12952                                 pw.write(info.stack, lastPos, pos-lastPos);
   12953                                 pw.println();
   12954                                 lastPos = pos+1;
   12955                             }
   12956                         }
   12957                         if (lastPos < info.stack.length()) {
   12958                             pw.print("        ");
   12959                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
   12960                             pw.println();
   12961                         }
   12962                     }
   12963                 }
   12964             }
   12965         }
   12966 
   12967         if (dumpPackage == null) {
   12968             pw.println();
   12969             needSep = false;
   12970             pw.println("  mStartedUsers:");
   12971             for (int i=0; i<mStartedUsers.size(); i++) {
   12972                 UserStartedState uss = mStartedUsers.valueAt(i);
   12973                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   12974                         pw.print(": "); uss.dump("", pw);
   12975             }
   12976             pw.print("  mStartedUserArray: [");
   12977             for (int i=0; i<mStartedUserArray.length; i++) {
   12978                 if (i > 0) pw.print(", ");
   12979                 pw.print(mStartedUserArray[i]);
   12980             }
   12981             pw.println("]");
   12982             pw.print("  mUserLru: [");
   12983             for (int i=0; i<mUserLru.size(); i++) {
   12984                 if (i > 0) pw.print(", ");
   12985                 pw.print(mUserLru.get(i));
   12986             }
   12987             pw.println("]");
   12988             if (dumpAll) {
   12989                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   12990             }
   12991             synchronized (mUserProfileGroupIdsSelfLocked) {
   12992                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
   12993                     pw.println("  mUserProfileGroupIds:");
   12994                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
   12995                         pw.print("    User #");
   12996                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
   12997                         pw.print(" -> profile #");
   12998                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
   12999                     }
   13000                 }
   13001             }
   13002         }
   13003         if (mHomeProcess != null && (dumpPackage == null
   13004                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   13005             if (needSep) {
   13006                 pw.println();
   13007                 needSep = false;
   13008             }
   13009             pw.println("  mHomeProcess: " + mHomeProcess);
   13010         }
   13011         if (mPreviousProcess != null && (dumpPackage == null
   13012                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   13013             if (needSep) {
   13014                 pw.println();
   13015                 needSep = false;
   13016             }
   13017             pw.println("  mPreviousProcess: " + mPreviousProcess);
   13018         }
   13019         if (dumpAll) {
   13020             StringBuilder sb = new StringBuilder(128);
   13021             sb.append("  mPreviousProcessVisibleTime: ");
   13022             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   13023             pw.println(sb);
   13024         }
   13025         if (mHeavyWeightProcess != null && (dumpPackage == null
   13026                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   13027             if (needSep) {
   13028                 pw.println();
   13029                 needSep = false;
   13030             }
   13031             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   13032         }
   13033         if (dumpPackage == null) {
   13034             pw.println("  mConfiguration: " + mConfiguration);
   13035         }
   13036         if (dumpAll) {
   13037             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   13038             if (mCompatModePackages.getPackages().size() > 0) {
   13039                 boolean printed = false;
   13040                 for (Map.Entry<String, Integer> entry
   13041                         : mCompatModePackages.getPackages().entrySet()) {
   13042                     String pkg = entry.getKey();
   13043                     int mode = entry.getValue();
   13044                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   13045                         continue;
   13046                     }
   13047                     if (!printed) {
   13048                         pw.println("  mScreenCompatPackages:");
   13049                         printed = true;
   13050                     }
   13051                     pw.print("    "); pw.print(pkg); pw.print(": ");
   13052                             pw.print(mode); pw.println();
   13053                 }
   13054             }
   13055         }
   13056         if (dumpPackage == null) {
   13057             pw.println("  mWakefulness="
   13058                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
   13059             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
   13060                     + lockScreenShownToString());
   13061             pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
   13062                     + " mTestPssMode=" + mTestPssMode);
   13063         }
   13064         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   13065                 || mOrigWaitForDebugger) {
   13066             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   13067                     || dumpPackage.equals(mOrigDebugApp)) {
   13068                 if (needSep) {
   13069                     pw.println();
   13070                     needSep = false;
   13071                 }
   13072                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   13073                         + " mDebugTransient=" + mDebugTransient
   13074                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   13075             }
   13076         }
   13077         if (mOpenGlTraceApp != null) {
   13078             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   13079                 if (needSep) {
   13080                     pw.println();
   13081                     needSep = false;
   13082                 }
   13083                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   13084             }
   13085         }
   13086         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   13087                 || mProfileFd != null) {
   13088             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   13089                 if (needSep) {
   13090                     pw.println();
   13091                     needSep = false;
   13092                 }
   13093                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   13094                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   13095                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   13096                         + mAutoStopProfiler);
   13097                 pw.println("  mProfileType=" + mProfileType);
   13098             }
   13099         }
   13100         if (dumpPackage == null) {
   13101             if (mAlwaysFinishActivities || mController != null) {
   13102                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   13103                         + " mController=" + mController);
   13104             }
   13105             if (dumpAll) {
   13106                 pw.println("  Total persistent processes: " + numPers);
   13107                 pw.println("  mProcessesReady=" + mProcessesReady
   13108                         + " mSystemReady=" + mSystemReady
   13109                         + " mBooted=" + mBooted
   13110                         + " mFactoryTest=" + mFactoryTest);
   13111                 pw.println("  mBooting=" + mBooting
   13112                         + " mCallFinishBooting=" + mCallFinishBooting
   13113                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   13114                 pw.print("  mLastPowerCheckRealtime=");
   13115                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   13116                         pw.println("");
   13117                 pw.print("  mLastPowerCheckUptime=");
   13118                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   13119                         pw.println("");
   13120                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   13121                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   13122                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   13123                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   13124                         + " (" + mLruProcesses.size() + " total)"
   13125                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   13126                         + " mNumServiceProcs=" + mNumServiceProcs
   13127                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   13128                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   13129                         + " mLastMemoryLevel" + mLastMemoryLevel
   13130                         + " mLastNumProcesses" + mLastNumProcesses);
   13131                 long now = SystemClock.uptimeMillis();
   13132                 pw.print("  mLastIdleTime=");
   13133                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   13134                         pw.print(" mLowRamSinceLastIdle=");
   13135                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   13136                         pw.println();
   13137             }
   13138         }
   13139 
   13140         if (!printedAnything) {
   13141             pw.println("  (nothing)");
   13142         }
   13143     }
   13144 
   13145     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   13146             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   13147         if (mProcessesToGc.size() > 0) {
   13148             boolean printed = false;
   13149             long now = SystemClock.uptimeMillis();
   13150             for (int i=0; i<mProcessesToGc.size(); i++) {
   13151                 ProcessRecord proc = mProcessesToGc.get(i);
   13152                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   13153                     continue;
   13154                 }
   13155                 if (!printed) {
   13156                     if (needSep) pw.println();
   13157                     needSep = true;
   13158                     pw.println("  Processes that are waiting to GC:");
   13159                     printed = true;
   13160                 }
   13161                 pw.print("    Process "); pw.println(proc);
   13162                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   13163                         pw.print(", last gced=");
   13164                         pw.print(now-proc.lastRequestedGc);
   13165                         pw.print(" ms ago, last lowMem=");
   13166                         pw.print(now-proc.lastLowMemory);
   13167                         pw.println(" ms ago");
   13168 
   13169             }
   13170         }
   13171         return needSep;
   13172     }
   13173 
   13174     void printOomLevel(PrintWriter pw, String name, int adj) {
   13175         pw.print("    ");
   13176         if (adj >= 0) {
   13177             pw.print(' ');
   13178             if (adj < 10) pw.print(' ');
   13179         } else {
   13180             if (adj > -10) pw.print(' ');
   13181         }
   13182         pw.print(adj);
   13183         pw.print(": ");
   13184         pw.print(name);
   13185         pw.print(" (");
   13186         pw.print(mProcessList.getMemLevel(adj)/1024);
   13187         pw.println(" kB)");
   13188     }
   13189 
   13190     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13191             int opti, boolean dumpAll) {
   13192         boolean needSep = false;
   13193 
   13194         if (mLruProcesses.size() > 0) {
   13195             if (needSep) pw.println();
   13196             needSep = true;
   13197             pw.println("  OOM levels:");
   13198             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   13199             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   13200             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   13201             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   13202             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   13203             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   13204             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   13205             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   13206             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   13207             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   13208             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   13209             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   13210             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   13211             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   13212 
   13213             if (needSep) pw.println();
   13214             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   13215                     pw.print(" total, non-act at ");
   13216                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   13217                     pw.print(", non-svc at ");
   13218                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   13219                     pw.println("):");
   13220             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   13221             needSep = true;
   13222         }
   13223 
   13224         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   13225 
   13226         pw.println();
   13227         pw.println("  mHomeProcess: " + mHomeProcess);
   13228         pw.println("  mPreviousProcess: " + mPreviousProcess);
   13229         if (mHeavyWeightProcess != null) {
   13230             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   13231         }
   13232 
   13233         return true;
   13234     }
   13235 
   13236     /**
   13237      * There are three ways to call this:
   13238      *  - no provider specified: dump all the providers
   13239      *  - a flattened component name that matched an existing provider was specified as the
   13240      *    first arg: dump that one provider
   13241      *  - the first arg isn't the flattened component name of an existing provider:
   13242      *    dump all providers whose component contains the first arg as a substring
   13243      */
   13244     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13245             int opti, boolean dumpAll) {
   13246         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   13247     }
   13248 
   13249     static class ItemMatcher {
   13250         ArrayList<ComponentName> components;
   13251         ArrayList<String> strings;
   13252         ArrayList<Integer> objects;
   13253         boolean all;
   13254 
   13255         ItemMatcher() {
   13256             all = true;
   13257         }
   13258 
   13259         void build(String name) {
   13260             ComponentName componentName = ComponentName.unflattenFromString(name);
   13261             if (componentName != null) {
   13262                 if (components == null) {
   13263                     components = new ArrayList<ComponentName>();
   13264                 }
   13265                 components.add(componentName);
   13266                 all = false;
   13267             } else {
   13268                 int objectId = 0;
   13269                 // Not a '/' separated full component name; maybe an object ID?
   13270                 try {
   13271                     objectId = Integer.parseInt(name, 16);
   13272                     if (objects == null) {
   13273                         objects = new ArrayList<Integer>();
   13274                     }
   13275                     objects.add(objectId);
   13276                     all = false;
   13277                 } catch (RuntimeException e) {
   13278                     // Not an integer; just do string match.
   13279                     if (strings == null) {
   13280                         strings = new ArrayList<String>();
   13281                     }
   13282                     strings.add(name);
   13283                     all = false;
   13284                 }
   13285             }
   13286         }
   13287 
   13288         int build(String[] args, int opti) {
   13289             for (; opti<args.length; opti++) {
   13290                 String name = args[opti];
   13291                 if ("--".equals(name)) {
   13292                     return opti+1;
   13293                 }
   13294                 build(name);
   13295             }
   13296             return opti;
   13297         }
   13298 
   13299         boolean match(Object object, ComponentName comp) {
   13300             if (all) {
   13301                 return true;
   13302             }
   13303             if (components != null) {
   13304                 for (int i=0; i<components.size(); i++) {
   13305                     if (components.get(i).equals(comp)) {
   13306                         return true;
   13307                     }
   13308                 }
   13309             }
   13310             if (objects != null) {
   13311                 for (int i=0; i<objects.size(); i++) {
   13312                     if (System.identityHashCode(object) == objects.get(i)) {
   13313                         return true;
   13314                     }
   13315                 }
   13316             }
   13317             if (strings != null) {
   13318                 String flat = comp.flattenToString();
   13319                 for (int i=0; i<strings.size(); i++) {
   13320                     if (flat.contains(strings.get(i))) {
   13321                         return true;
   13322                     }
   13323                 }
   13324             }
   13325             return false;
   13326         }
   13327     }
   13328 
   13329     /**
   13330      * There are three things that cmd can be:
   13331      *  - a flattened component name that matches an existing activity
   13332      *  - the cmd arg isn't the flattened component name of an existing activity:
   13333      *    dump all activity whose component contains the cmd as a substring
   13334      *  - A hex number of the ActivityRecord object instance.
   13335      */
   13336     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13337             int opti, boolean dumpAll) {
   13338         ArrayList<ActivityRecord> activities;
   13339 
   13340         synchronized (this) {
   13341             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   13342         }
   13343 
   13344         if (activities.size() <= 0) {
   13345             return false;
   13346         }
   13347 
   13348         String[] newArgs = new String[args.length - opti];
   13349         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   13350 
   13351         TaskRecord lastTask = null;
   13352         boolean needSep = false;
   13353         for (int i=activities.size()-1; i>=0; i--) {
   13354             ActivityRecord r = activities.get(i);
   13355             if (needSep) {
   13356                 pw.println();
   13357             }
   13358             needSep = true;
   13359             synchronized (this) {
   13360                 if (lastTask != r.task) {
   13361                     lastTask = r.task;
   13362                     pw.print("TASK "); pw.print(lastTask.affinity);
   13363                             pw.print(" id="); pw.println(lastTask.taskId);
   13364                     if (dumpAll) {
   13365                         lastTask.dump(pw, "  ");
   13366                     }
   13367                 }
   13368             }
   13369             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   13370         }
   13371         return true;
   13372     }
   13373 
   13374     /**
   13375      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   13376      * there is a thread associated with the activity.
   13377      */
   13378     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   13379             final ActivityRecord r, String[] args, boolean dumpAll) {
   13380         String innerPrefix = prefix + "  ";
   13381         synchronized (this) {
   13382             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   13383                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   13384                     pw.print(" pid=");
   13385                     if (r.app != null) pw.println(r.app.pid);
   13386                     else pw.println("(not running)");
   13387             if (dumpAll) {
   13388                 r.dump(pw, innerPrefix);
   13389             }
   13390         }
   13391         if (r.app != null && r.app.thread != null) {
   13392             // flush anything that is already in the PrintWriter since the thread is going
   13393             // to write to the file descriptor directly
   13394             pw.flush();
   13395             try {
   13396                 TransferPipe tp = new TransferPipe();
   13397                 try {
   13398                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   13399                             r.appToken, innerPrefix, args);
   13400                     tp.go(fd);
   13401                 } finally {
   13402                     tp.kill();
   13403                 }
   13404             } catch (IOException e) {
   13405                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   13406             } catch (RemoteException e) {
   13407                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   13408             }
   13409         }
   13410     }
   13411 
   13412     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13413             int opti, boolean dumpAll, String dumpPackage) {
   13414         boolean needSep = false;
   13415         boolean onlyHistory = false;
   13416         boolean printedAnything = false;
   13417 
   13418         if ("history".equals(dumpPackage)) {
   13419             if (opti < args.length && "-s".equals(args[opti])) {
   13420                 dumpAll = false;
   13421             }
   13422             onlyHistory = true;
   13423             dumpPackage = null;
   13424         }
   13425 
   13426         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   13427         if (!onlyHistory && dumpAll) {
   13428             if (mRegisteredReceivers.size() > 0) {
   13429                 boolean printed = false;
   13430                 Iterator it = mRegisteredReceivers.values().iterator();
   13431                 while (it.hasNext()) {
   13432                     ReceiverList r = (ReceiverList)it.next();
   13433                     if (dumpPackage != null && (r.app == null ||
   13434                             !dumpPackage.equals(r.app.info.packageName))) {
   13435                         continue;
   13436                     }
   13437                     if (!printed) {
   13438                         pw.println("  Registered Receivers:");
   13439                         needSep = true;
   13440                         printed = true;
   13441                         printedAnything = true;
   13442                     }
   13443                     pw.print("  * "); pw.println(r);
   13444                     r.dump(pw, "    ");
   13445                 }
   13446             }
   13447 
   13448             if (mReceiverResolver.dump(pw, needSep ?
   13449                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   13450                     "    ", dumpPackage, false, false)) {
   13451                 needSep = true;
   13452                 printedAnything = true;
   13453             }
   13454         }
   13455 
   13456         for (BroadcastQueue q : mBroadcastQueues) {
   13457             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   13458             printedAnything |= needSep;
   13459         }
   13460 
   13461         needSep = true;
   13462 
   13463         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   13464             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   13465                 if (needSep) {
   13466                     pw.println();
   13467                 }
   13468                 needSep = true;
   13469                 printedAnything = true;
   13470                 pw.print("  Sticky broadcasts for user ");
   13471                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   13472                 StringBuilder sb = new StringBuilder(128);
   13473                 for (Map.Entry<String, ArrayList<Intent>> ent
   13474                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   13475                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   13476                     if (dumpAll) {
   13477                         pw.println(":");
   13478                         ArrayList<Intent> intents = ent.getValue();
   13479                         final int N = intents.size();
   13480                         for (int i=0; i<N; i++) {
   13481                             sb.setLength(0);
   13482                             sb.append("    Intent: ");
   13483                             intents.get(i).toShortString(sb, false, true, false, false);
   13484                             pw.println(sb.toString());
   13485                             Bundle bundle = intents.get(i).getExtras();
   13486                             if (bundle != null) {
   13487                                 pw.print("      ");
   13488                                 pw.println(bundle.toString());
   13489                             }
   13490                         }
   13491                     } else {
   13492                         pw.println("");
   13493                     }
   13494                 }
   13495             }
   13496         }
   13497 
   13498         if (!onlyHistory && dumpAll) {
   13499             pw.println();
   13500             for (BroadcastQueue queue : mBroadcastQueues) {
   13501                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   13502                         + queue.mBroadcastsScheduled);
   13503             }
   13504             pw.println("  mHandler:");
   13505             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   13506             needSep = true;
   13507             printedAnything = true;
   13508         }
   13509 
   13510         if (!printedAnything) {
   13511             pw.println("  (nothing)");
   13512         }
   13513     }
   13514 
   13515     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13516             int opti, boolean dumpAll, String dumpPackage) {
   13517         boolean needSep;
   13518         boolean printedAnything = false;
   13519 
   13520         ItemMatcher matcher = new ItemMatcher();
   13521         matcher.build(args, opti);
   13522 
   13523         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   13524 
   13525         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   13526         printedAnything |= needSep;
   13527 
   13528         if (mLaunchingProviders.size() > 0) {
   13529             boolean printed = false;
   13530             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   13531                 ContentProviderRecord r = mLaunchingProviders.get(i);
   13532                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   13533                     continue;
   13534                 }
   13535                 if (!printed) {
   13536                     if (needSep) pw.println();
   13537                     needSep = true;
   13538                     pw.println("  Launching content providers:");
   13539                     printed = true;
   13540                     printedAnything = true;
   13541                 }
   13542                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   13543                         pw.println(r);
   13544             }
   13545         }
   13546 
   13547         if (mGrantedUriPermissions.size() > 0) {
   13548             boolean printed = false;
   13549             int dumpUid = -2;
   13550             if (dumpPackage != null) {
   13551                 try {
   13552                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   13553                 } catch (NameNotFoundException e) {
   13554                     dumpUid = -1;
   13555                 }
   13556             }
   13557             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   13558                 int uid = mGrantedUriPermissions.keyAt(i);
   13559                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   13560                     continue;
   13561                 }
   13562                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   13563                 if (!printed) {
   13564                     if (needSep) pw.println();
   13565                     needSep = true;
   13566                     pw.println("  Granted Uri Permissions:");
   13567                     printed = true;
   13568                     printedAnything = true;
   13569                 }
   13570                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   13571                 for (UriPermission perm : perms.values()) {
   13572                     pw.print("    "); pw.println(perm);
   13573                     if (dumpAll) {
   13574                         perm.dump(pw, "      ");
   13575                     }
   13576                 }
   13577             }
   13578         }
   13579 
   13580         if (!printedAnything) {
   13581             pw.println("  (nothing)");
   13582         }
   13583     }
   13584 
   13585     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13586             int opti, boolean dumpAll, String dumpPackage) {
   13587         boolean printed = false;
   13588 
   13589         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   13590 
   13591         if (mIntentSenderRecords.size() > 0) {
   13592             Iterator<WeakReference<PendingIntentRecord>> it
   13593                     = mIntentSenderRecords.values().iterator();
   13594             while (it.hasNext()) {
   13595                 WeakReference<PendingIntentRecord> ref = it.next();
   13596                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   13597                 if (dumpPackage != null && (rec == null
   13598                         || !dumpPackage.equals(rec.key.packageName))) {
   13599                     continue;
   13600                 }
   13601                 printed = true;
   13602                 if (rec != null) {
   13603                     pw.print("  * "); pw.println(rec);
   13604                     if (dumpAll) {
   13605                         rec.dump(pw, "    ");
   13606                     }
   13607                 } else {
   13608                     pw.print("  * "); pw.println(ref);
   13609                 }
   13610             }
   13611         }
   13612 
   13613         if (!printed) {
   13614             pw.println("  (nothing)");
   13615         }
   13616     }
   13617 
   13618     private static final int dumpProcessList(PrintWriter pw,
   13619             ActivityManagerService service, List list,
   13620             String prefix, String normalLabel, String persistentLabel,
   13621             String dumpPackage) {
   13622         int numPers = 0;
   13623         final int N = list.size()-1;
   13624         for (int i=N; i>=0; i--) {
   13625             ProcessRecord r = (ProcessRecord)list.get(i);
   13626             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   13627                 continue;
   13628             }
   13629             pw.println(String.format("%s%s #%2d: %s",
   13630                     prefix, (r.persistent ? persistentLabel : normalLabel),
   13631                     i, r.toString()));
   13632             if (r.persistent) {
   13633                 numPers++;
   13634             }
   13635         }
   13636         return numPers;
   13637     }
   13638 
   13639     private static final boolean dumpProcessOomList(PrintWriter pw,
   13640             ActivityManagerService service, List<ProcessRecord> origList,
   13641             String prefix, String normalLabel, String persistentLabel,
   13642             boolean inclDetails, String dumpPackage) {
   13643 
   13644         ArrayList<Pair<ProcessRecord, Integer>> list
   13645                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   13646         for (int i=0; i<origList.size(); i++) {
   13647             ProcessRecord r = origList.get(i);
   13648             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   13649                 continue;
   13650             }
   13651             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   13652         }
   13653 
   13654         if (list.size() <= 0) {
   13655             return false;
   13656         }
   13657 
   13658         Comparator<Pair<ProcessRecord, Integer>> comparator
   13659                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   13660             @Override
   13661             public int compare(Pair<ProcessRecord, Integer> object1,
   13662                     Pair<ProcessRecord, Integer> object2) {
   13663                 if (object1.first.setAdj != object2.first.setAdj) {
   13664                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   13665                 }
   13666                 if (object1.second.intValue() != object2.second.intValue()) {
   13667                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   13668                 }
   13669                 return 0;
   13670             }
   13671         };
   13672 
   13673         Collections.sort(list, comparator);
   13674 
   13675         final long curRealtime = SystemClock.elapsedRealtime();
   13676         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   13677         final long curUptime = SystemClock.uptimeMillis();
   13678         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   13679 
   13680         for (int i=list.size()-1; i>=0; i--) {
   13681             ProcessRecord r = list.get(i).first;
   13682             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   13683             char schedGroup;
   13684             switch (r.setSchedGroup) {
   13685                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   13686                     schedGroup = 'B';
   13687                     break;
   13688                 case Process.THREAD_GROUP_DEFAULT:
   13689                     schedGroup = 'F';
   13690                     break;
   13691                 default:
   13692                     schedGroup = '?';
   13693                     break;
   13694             }
   13695             char foreground;
   13696             if (r.foregroundActivities) {
   13697                 foreground = 'A';
   13698             } else if (r.foregroundServices) {
   13699                 foreground = 'S';
   13700             } else {
   13701                 foreground = ' ';
   13702             }
   13703             String procState = ProcessList.makeProcStateString(r.curProcState);
   13704             pw.print(prefix);
   13705             pw.print(r.persistent ? persistentLabel : normalLabel);
   13706             pw.print(" #");
   13707             int num = (origList.size()-1)-list.get(i).second;
   13708             if (num < 10) pw.print(' ');
   13709             pw.print(num);
   13710             pw.print(": ");
   13711             pw.print(oomAdj);
   13712             pw.print(' ');
   13713             pw.print(schedGroup);
   13714             pw.print('/');
   13715             pw.print(foreground);
   13716             pw.print('/');
   13717             pw.print(procState);
   13718             pw.print(" trm:");
   13719             if (r.trimMemoryLevel < 10) pw.print(' ');
   13720             pw.print(r.trimMemoryLevel);
   13721             pw.print(' ');
   13722             pw.print(r.toShortString());
   13723             pw.print(" (");
   13724             pw.print(r.adjType);
   13725             pw.println(')');
   13726             if (r.adjSource != null || r.adjTarget != null) {
   13727                 pw.print(prefix);
   13728                 pw.print("    ");
   13729                 if (r.adjTarget instanceof ComponentName) {
   13730                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   13731                 } else if (r.adjTarget != null) {
   13732                     pw.print(r.adjTarget.toString());
   13733                 } else {
   13734                     pw.print("{null}");
   13735                 }
   13736                 pw.print("<=");
   13737                 if (r.adjSource instanceof ProcessRecord) {
   13738                     pw.print("Proc{");
   13739                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   13740                     pw.println("}");
   13741                 } else if (r.adjSource != null) {
   13742                     pw.println(r.adjSource.toString());
   13743                 } else {
   13744                     pw.println("{null}");
   13745                 }
   13746             }
   13747             if (inclDetails) {
   13748                 pw.print(prefix);
   13749                 pw.print("    ");
   13750                 pw.print("oom: max="); pw.print(r.maxAdj);
   13751                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   13752                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   13753                 pw.print(" cur="); pw.print(r.curAdj);
   13754                 pw.print(" set="); pw.println(r.setAdj);
   13755                 pw.print(prefix);
   13756                 pw.print("    ");
   13757                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   13758                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   13759                 pw.print(" lastPss="); pw.print(r.lastPss);
   13760                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   13761                 pw.print(prefix);
   13762                 pw.print("    ");
   13763                 pw.print("cached="); pw.print(r.cached);
   13764                 pw.print(" empty="); pw.print(r.empty);
   13765                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   13766 
   13767                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   13768                     if (r.lastWakeTime != 0) {
   13769                         long wtime;
   13770                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   13771                         synchronized (stats) {
   13772                             wtime = stats.getProcessWakeTime(r.info.uid,
   13773                                     r.pid, curRealtime);
   13774                         }
   13775                         long timeUsed = wtime - r.lastWakeTime;
   13776                         pw.print(prefix);
   13777                         pw.print("    ");
   13778                         pw.print("keep awake over ");
   13779                         TimeUtils.formatDuration(realtimeSince, pw);
   13780                         pw.print(" used ");
   13781                         TimeUtils.formatDuration(timeUsed, pw);
   13782                         pw.print(" (");
   13783                         pw.print((timeUsed*100)/realtimeSince);
   13784                         pw.println("%)");
   13785                     }
   13786                     if (r.lastCpuTime != 0) {
   13787                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   13788                         pw.print(prefix);
   13789                         pw.print("    ");
   13790                         pw.print("run cpu over ");
   13791                         TimeUtils.formatDuration(uptimeSince, pw);
   13792                         pw.print(" used ");
   13793                         TimeUtils.formatDuration(timeUsed, pw);
   13794                         pw.print(" (");
   13795                         pw.print((timeUsed*100)/uptimeSince);
   13796                         pw.println("%)");
   13797                     }
   13798                 }
   13799             }
   13800         }
   13801         return true;
   13802     }
   13803 
   13804     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   13805             String[] args) {
   13806         ArrayList<ProcessRecord> procs;
   13807         synchronized (this) {
   13808             if (args != null && args.length > start
   13809                     && args[start].charAt(0) != '-') {
   13810                 procs = new ArrayList<ProcessRecord>();
   13811                 int pid = -1;
   13812                 try {
   13813                     pid = Integer.parseInt(args[start]);
   13814                 } catch (NumberFormatException e) {
   13815                 }
   13816                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13817                     ProcessRecord proc = mLruProcesses.get(i);
   13818                     if (proc.pid == pid) {
   13819                         procs.add(proc);
   13820                     } else if (allPkgs && proc.pkgList != null
   13821                             && proc.pkgList.containsKey(args[start])) {
   13822                         procs.add(proc);
   13823                     } else if (proc.processName.equals(args[start])) {
   13824                         procs.add(proc);
   13825                     }
   13826                 }
   13827                 if (procs.size() <= 0) {
   13828                     return null;
   13829                 }
   13830             } else {
   13831                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   13832             }
   13833         }
   13834         return procs;
   13835     }
   13836 
   13837     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   13838             PrintWriter pw, String[] args) {
   13839         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13840         if (procs == null) {
   13841             pw.println("No process found for: " + args[0]);
   13842             return;
   13843         }
   13844 
   13845         long uptime = SystemClock.uptimeMillis();
   13846         long realtime = SystemClock.elapsedRealtime();
   13847         pw.println("Applications Graphics Acceleration Info:");
   13848         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   13849 
   13850         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13851             ProcessRecord r = procs.get(i);
   13852             if (r.thread != null) {
   13853                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   13854                 pw.flush();
   13855                 try {
   13856                     TransferPipe tp = new TransferPipe();
   13857                     try {
   13858                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   13859                         tp.go(fd);
   13860                     } finally {
   13861                         tp.kill();
   13862                     }
   13863                 } catch (IOException e) {
   13864                     pw.println("Failure while dumping the app: " + r);
   13865                     pw.flush();
   13866                 } catch (RemoteException e) {
   13867                     pw.println("Got a RemoteException while dumping the app " + r);
   13868                     pw.flush();
   13869                 }
   13870             }
   13871         }
   13872     }
   13873 
   13874     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   13875         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13876         if (procs == null) {
   13877             pw.println("No process found for: " + args[0]);
   13878             return;
   13879         }
   13880 
   13881         pw.println("Applications Database Info:");
   13882 
   13883         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13884             ProcessRecord r = procs.get(i);
   13885             if (r.thread != null) {
   13886                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   13887                 pw.flush();
   13888                 try {
   13889                     TransferPipe tp = new TransferPipe();
   13890                     try {
   13891                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   13892                         tp.go(fd);
   13893                     } finally {
   13894                         tp.kill();
   13895                     }
   13896                 } catch (IOException e) {
   13897                     pw.println("Failure while dumping the app: " + r);
   13898                     pw.flush();
   13899                 } catch (RemoteException e) {
   13900                     pw.println("Got a RemoteException while dumping the app " + r);
   13901                     pw.flush();
   13902                 }
   13903             }
   13904         }
   13905     }
   13906 
   13907     final static class MemItem {
   13908         final boolean isProc;
   13909         final String label;
   13910         final String shortLabel;
   13911         final long pss;
   13912         final int id;
   13913         final boolean hasActivities;
   13914         ArrayList<MemItem> subitems;
   13915 
   13916         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   13917                 boolean _hasActivities) {
   13918             isProc = true;
   13919             label = _label;
   13920             shortLabel = _shortLabel;
   13921             pss = _pss;
   13922             id = _id;
   13923             hasActivities = _hasActivities;
   13924         }
   13925 
   13926         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   13927             isProc = false;
   13928             label = _label;
   13929             shortLabel = _shortLabel;
   13930             pss = _pss;
   13931             id = _id;
   13932             hasActivities = false;
   13933         }
   13934     }
   13935 
   13936     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   13937             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   13938         if (sort && !isCompact) {
   13939             Collections.sort(items, new Comparator<MemItem>() {
   13940                 @Override
   13941                 public int compare(MemItem lhs, MemItem rhs) {
   13942                     if (lhs.pss < rhs.pss) {
   13943                         return 1;
   13944                     } else if (lhs.pss > rhs.pss) {
   13945                         return -1;
   13946                     }
   13947                     return 0;
   13948                 }
   13949             });
   13950         }
   13951 
   13952         for (int i=0; i<items.size(); i++) {
   13953             MemItem mi = items.get(i);
   13954             if (!isCompact) {
   13955                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   13956             } else if (mi.isProc) {
   13957                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   13958                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   13959                 pw.println(mi.hasActivities ? ",a" : ",e");
   13960             } else {
   13961                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   13962                 pw.println(mi.pss);
   13963             }
   13964             if (mi.subitems != null) {
   13965                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   13966                         true, isCompact);
   13967             }
   13968         }
   13969     }
   13970 
   13971     // These are in KB.
   13972     static final long[] DUMP_MEM_BUCKETS = new long[] {
   13973         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   13974         120*1024, 160*1024, 200*1024,
   13975         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   13976         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   13977     };
   13978 
   13979     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   13980             boolean stackLike) {
   13981         int start = label.lastIndexOf('.');
   13982         if (start >= 0) start++;
   13983         else start = 0;
   13984         int end = label.length();
   13985         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   13986             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   13987                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   13988                 out.append(bucket);
   13989                 out.append(stackLike ? "MB." : "MB ");
   13990                 out.append(label, start, end);
   13991                 return;
   13992             }
   13993         }
   13994         out.append(memKB/1024);
   13995         out.append(stackLike ? "MB." : "MB ");
   13996         out.append(label, start, end);
   13997     }
   13998 
   13999     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   14000             ProcessList.NATIVE_ADJ,
   14001             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   14002             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   14003             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   14004             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   14005             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   14006             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   14007     };
   14008     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   14009             "Native",
   14010             "System", "Persistent", "Persistent Service", "Foreground",
   14011             "Visible", "Perceptible",
   14012             "Heavy Weight", "Backup",
   14013             "A Services", "Home",
   14014             "Previous", "B Services", "Cached"
   14015     };
   14016     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   14017             "native",
   14018             "sys", "pers", "persvc", "fore",
   14019             "vis", "percept",
   14020             "heavy", "backup",
   14021             "servicea", "home",
   14022             "prev", "serviceb", "cached"
   14023     };
   14024 
   14025     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   14026             long realtime, boolean isCheckinRequest, boolean isCompact) {
   14027         if (isCheckinRequest || isCompact) {
   14028             // short checkin version
   14029             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   14030         } else {
   14031             pw.println("Applications Memory Usage (kB):");
   14032             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   14033         }
   14034     }
   14035 
   14036     private static final int KSM_SHARED = 0;
   14037     private static final int KSM_SHARING = 1;
   14038     private static final int KSM_UNSHARED = 2;
   14039     private static final int KSM_VOLATILE = 3;
   14040 
   14041     private final long[] getKsmInfo() {
   14042         long[] longOut = new long[4];
   14043         final int[] SINGLE_LONG_FORMAT = new int[] {
   14044             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   14045         };
   14046         long[] longTmp = new long[1];
   14047         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   14048                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14049         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14050         longTmp[0] = 0;
   14051         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   14052                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14053         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14054         longTmp[0] = 0;
   14055         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   14056                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14057         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14058         longTmp[0] = 0;
   14059         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   14060                 SINGLE_LONG_FORMAT, null, longTmp, null);
   14061         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
   14062         return longOut;
   14063     }
   14064 
   14065     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   14066             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   14067         boolean dumpDetails = false;
   14068         boolean dumpFullDetails = false;
   14069         boolean dumpDalvik = false;
   14070         boolean oomOnly = false;
   14071         boolean isCompact = false;
   14072         boolean localOnly = false;
   14073         boolean packages = false;
   14074 
   14075         int opti = 0;
   14076         while (opti < args.length) {
   14077             String opt = args[opti];
   14078             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   14079                 break;
   14080             }
   14081             opti++;
   14082             if ("-a".equals(opt)) {
   14083                 dumpDetails = true;
   14084                 dumpFullDetails = true;
   14085                 dumpDalvik = true;
   14086             } else if ("-d".equals(opt)) {
   14087                 dumpDalvik = true;
   14088             } else if ("-c".equals(opt)) {
   14089                 isCompact = true;
   14090             } else if ("--oom".equals(opt)) {
   14091                 oomOnly = true;
   14092             } else if ("--local".equals(opt)) {
   14093                 localOnly = true;
   14094             } else if ("--package".equals(opt)) {
   14095                 packages = true;
   14096             } else if ("-h".equals(opt)) {
   14097                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   14098                 pw.println("  -a: include all available information for each process.");
   14099                 pw.println("  -d: include dalvik details when dumping process details.");
   14100                 pw.println("  -c: dump in a compact machine-parseable representation.");
   14101                 pw.println("  --oom: only show processes organized by oom adj.");
   14102                 pw.println("  --local: only collect details locally, don't call process.");
   14103                 pw.println("  --package: interpret process arg as package, dumping all");
   14104                 pw.println("             processes that have loaded that package.");
   14105                 pw.println("If [process] is specified it can be the name or ");
   14106                 pw.println("pid of a specific process to dump.");
   14107                 return;
   14108             } else {
   14109                 pw.println("Unknown argument: " + opt + "; use -h for help");
   14110             }
   14111         }
   14112 
   14113         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   14114         long uptime = SystemClock.uptimeMillis();
   14115         long realtime = SystemClock.elapsedRealtime();
   14116         final long[] tmpLong = new long[1];
   14117 
   14118         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   14119         if (procs == null) {
   14120             // No Java processes.  Maybe they want to print a native process.
   14121             if (args != null && args.length > opti
   14122                     && args[opti].charAt(0) != '-') {
   14123                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   14124                         = new ArrayList<ProcessCpuTracker.Stats>();
   14125                 updateCpuStatsNow();
   14126                 int findPid = -1;
   14127                 try {
   14128                     findPid = Integer.parseInt(args[opti]);
   14129                 } catch (NumberFormatException e) {
   14130                 }
   14131                 synchronized (mProcessCpuTracker) {
   14132                     final int N = mProcessCpuTracker.countStats();
   14133                     for (int i=0; i<N; i++) {
   14134                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14135                         if (st.pid == findPid || (st.baseName != null
   14136                                 && st.baseName.equals(args[opti]))) {
   14137                             nativeProcs.add(st);
   14138                         }
   14139                     }
   14140                 }
   14141                 if (nativeProcs.size() > 0) {
   14142                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   14143                             isCompact);
   14144                     Debug.MemoryInfo mi = null;
   14145                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   14146                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   14147                         final int pid = r.pid;
   14148                         if (!isCheckinRequest && dumpDetails) {
   14149                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   14150                         }
   14151                         if (mi == null) {
   14152                             mi = new Debug.MemoryInfo();
   14153                         }
   14154                         if (dumpDetails || (!brief && !oomOnly)) {
   14155                             Debug.getMemoryInfo(pid, mi);
   14156                         } else {
   14157                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   14158                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   14159                         }
   14160                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14161                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   14162                         if (isCheckinRequest) {
   14163                             pw.println();
   14164                         }
   14165                     }
   14166                     return;
   14167                 }
   14168             }
   14169             pw.println("No process found for: " + args[opti]);
   14170             return;
   14171         }
   14172 
   14173         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   14174             dumpDetails = true;
   14175         }
   14176 
   14177         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   14178 
   14179         String[] innerArgs = new String[args.length-opti];
   14180         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   14181 
   14182         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   14183         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   14184         long nativePss = 0;
   14185         long dalvikPss = 0;
   14186         long otherPss = 0;
   14187         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   14188 
   14189         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   14190         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   14191                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   14192 
   14193         long totalPss = 0;
   14194         long cachedPss = 0;
   14195 
   14196         Debug.MemoryInfo mi = null;
   14197         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   14198             final ProcessRecord r = procs.get(i);
   14199             final IApplicationThread thread;
   14200             final int pid;
   14201             final int oomAdj;
   14202             final boolean hasActivities;
   14203             synchronized (this) {
   14204                 thread = r.thread;
   14205                 pid = r.pid;
   14206                 oomAdj = r.getSetAdjWithServices();
   14207                 hasActivities = r.activities.size() > 0;
   14208             }
   14209             if (thread != null) {
   14210                 if (!isCheckinRequest && dumpDetails) {
   14211                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   14212                 }
   14213                 if (mi == null) {
   14214                     mi = new Debug.MemoryInfo();
   14215                 }
   14216                 if (dumpDetails || (!brief && !oomOnly)) {
   14217                     Debug.getMemoryInfo(pid, mi);
   14218                 } else {
   14219                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
   14220                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   14221                 }
   14222                 if (dumpDetails) {
   14223                     if (localOnly) {
   14224                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14225                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
   14226                         if (isCheckinRequest) {
   14227                             pw.println();
   14228                         }
   14229                     } else {
   14230                         try {
   14231                             pw.flush();
   14232                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   14233                                     dumpDalvik, innerArgs);
   14234                         } catch (RemoteException e) {
   14235                             if (!isCheckinRequest) {
   14236                                 pw.println("Got RemoteException!");
   14237                                 pw.flush();
   14238                             }
   14239                         }
   14240                     }
   14241                 }
   14242 
   14243                 final long myTotalPss = mi.getTotalPss();
   14244                 final long myTotalUss = mi.getTotalUss();
   14245 
   14246                 synchronized (this) {
   14247                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   14248                         // Record this for posterity if the process has been stable.
   14249                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   14250                     }
   14251                 }
   14252 
   14253                 if (!isCheckinRequest && mi != null) {
   14254                     totalPss += myTotalPss;
   14255                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   14256                             (hasActivities ? " / activities)" : ")"),
   14257                             r.processName, myTotalPss, pid, hasActivities);
   14258                     procMems.add(pssItem);
   14259                     procMemsMap.put(pid, pssItem);
   14260 
   14261                     nativePss += mi.nativePss;
   14262                     dalvikPss += mi.dalvikPss;
   14263                     otherPss += mi.otherPss;
   14264                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14265                         long mem = mi.getOtherPss(j);
   14266                         miscPss[j] += mem;
   14267                         otherPss -= mem;
   14268                     }
   14269 
   14270                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14271                         cachedPss += myTotalPss;
   14272                     }
   14273 
   14274                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   14275                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   14276                                 || oomIndex == (oomPss.length-1)) {
   14277                             oomPss[oomIndex] += myTotalPss;
   14278                             if (oomProcs[oomIndex] == null) {
   14279                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   14280                             }
   14281                             oomProcs[oomIndex].add(pssItem);
   14282                             break;
   14283                         }
   14284                     }
   14285                 }
   14286             }
   14287         }
   14288 
   14289         long nativeProcTotalPss = 0;
   14290 
   14291         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   14292             // If we are showing aggregations, also look for native processes to
   14293             // include so that our aggregations are more accurate.
   14294             updateCpuStatsNow();
   14295             mi = null;
   14296             synchronized (mProcessCpuTracker) {
   14297                 final int N = mProcessCpuTracker.countStats();
   14298                 for (int i=0; i<N; i++) {
   14299                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14300                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   14301                         if (mi == null) {
   14302                             mi = new Debug.MemoryInfo();
   14303                         }
   14304                         if (!brief && !oomOnly) {
   14305                             Debug.getMemoryInfo(st.pid, mi);
   14306                         } else {
   14307                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
   14308                             mi.nativePrivateDirty = (int)tmpLong[0];
   14309                         }
   14310 
   14311                         final long myTotalPss = mi.getTotalPss();
   14312                         totalPss += myTotalPss;
   14313                         nativeProcTotalPss += myTotalPss;
   14314 
   14315                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   14316                                 st.name, myTotalPss, st.pid, false);
   14317                         procMems.add(pssItem);
   14318 
   14319                         nativePss += mi.nativePss;
   14320                         dalvikPss += mi.dalvikPss;
   14321                         otherPss += mi.otherPss;
   14322                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14323                             long mem = mi.getOtherPss(j);
   14324                             miscPss[j] += mem;
   14325                             otherPss -= mem;
   14326                         }
   14327                         oomPss[0] += myTotalPss;
   14328                         if (oomProcs[0] == null) {
   14329                             oomProcs[0] = new ArrayList<MemItem>();
   14330                         }
   14331                         oomProcs[0].add(pssItem);
   14332                     }
   14333                 }
   14334             }
   14335 
   14336             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   14337 
   14338             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   14339             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   14340             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   14341             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14342                 String label = Debug.MemoryInfo.getOtherLabel(j);
   14343                 catMems.add(new MemItem(label, label, miscPss[j], j));
   14344             }
   14345 
   14346             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   14347             for (int j=0; j<oomPss.length; j++) {
   14348                 if (oomPss[j] != 0) {
   14349                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   14350                             : DUMP_MEM_OOM_LABEL[j];
   14351                     MemItem item = new MemItem(label, label, oomPss[j],
   14352                             DUMP_MEM_OOM_ADJ[j]);
   14353                     item.subitems = oomProcs[j];
   14354                     oomMems.add(item);
   14355                 }
   14356             }
   14357 
   14358             if (!brief && !oomOnly && !isCompact) {
   14359                 pw.println();
   14360                 pw.println("Total PSS by process:");
   14361                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   14362                 pw.println();
   14363             }
   14364             if (!isCompact) {
   14365                 pw.println("Total PSS by OOM adjustment:");
   14366             }
   14367             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   14368             if (!brief && !oomOnly) {
   14369                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   14370                 if (!isCompact) {
   14371                     out.println();
   14372                     out.println("Total PSS by category:");
   14373                 }
   14374                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   14375             }
   14376             if (!isCompact) {
   14377                 pw.println();
   14378             }
   14379             MemInfoReader memInfo = new MemInfoReader();
   14380             memInfo.readMemInfo();
   14381             if (nativeProcTotalPss > 0) {
   14382                 synchronized (this) {
   14383                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
   14384                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
   14385                             memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
   14386                 }
   14387             }
   14388             if (!brief) {
   14389                 if (!isCompact) {
   14390                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   14391                     pw.print(" kB (status ");
   14392                     switch (mLastMemoryLevel) {
   14393                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   14394                             pw.println("normal)");
   14395                             break;
   14396                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   14397                             pw.println("moderate)");
   14398                             break;
   14399                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   14400                             pw.println("low)");
   14401                             break;
   14402                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   14403                             pw.println("critical)");
   14404                             break;
   14405                         default:
   14406                             pw.print(mLastMemoryLevel);
   14407                             pw.println(")");
   14408                             break;
   14409                     }
   14410                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   14411                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   14412                             pw.print(cachedPss); pw.print(" cached pss + ");
   14413                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
   14414                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   14415                 } else {
   14416                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   14417                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   14418                             + memInfo.getFreeSizeKb()); pw.print(",");
   14419                     pw.println(totalPss - cachedPss);
   14420                 }
   14421             }
   14422             if (!isCompact) {
   14423                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   14424                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
   14425                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   14426                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
   14427                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   14428                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   14429                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
   14430             }
   14431             if (!brief) {
   14432                 if (memInfo.getZramTotalSizeKb() != 0) {
   14433                     if (!isCompact) {
   14434                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   14435                                 pw.print(" kB physical used for ");
   14436                                 pw.print(memInfo.getSwapTotalSizeKb()
   14437                                         - memInfo.getSwapFreeSizeKb());
   14438                                 pw.print(" kB in swap (");
   14439                                 pw.print(memInfo.getSwapTotalSizeKb());
   14440                                 pw.println(" kB total swap)");
   14441                     } else {
   14442                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   14443                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   14444                                 pw.println(memInfo.getSwapFreeSizeKb());
   14445                     }
   14446                 }
   14447                 final long[] ksm = getKsmInfo();
   14448                 if (!isCompact) {
   14449                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   14450                             || ksm[KSM_VOLATILE] != 0) {
   14451                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
   14452                                 pw.print(" kB saved from shared ");
   14453                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
   14454                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
   14455                                 pw.print(" kB unshared; ");
   14456                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
   14457                     }
   14458                     pw.print("   Tuning: ");
   14459                     pw.print(ActivityManager.staticGetMemoryClass());
   14460                     pw.print(" (large ");
   14461                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14462                     pw.print("), oom ");
   14463                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14464                     pw.print(" kB");
   14465                     pw.print(", restore limit ");
   14466                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   14467                     pw.print(" kB");
   14468                     if (ActivityManager.isLowRamDeviceStatic()) {
   14469                         pw.print(" (low-ram)");
   14470                     }
   14471                     if (ActivityManager.isHighEndGfx()) {
   14472                         pw.print(" (high-end-gfx)");
   14473                     }
   14474                     pw.println();
   14475                 } else {
   14476                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
   14477                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
   14478                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
   14479                     pw.print("tuning,");
   14480                     pw.print(ActivityManager.staticGetMemoryClass());
   14481                     pw.print(',');
   14482                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14483                     pw.print(',');
   14484                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14485                     if (ActivityManager.isLowRamDeviceStatic()) {
   14486                         pw.print(",low-ram");
   14487                     }
   14488                     if (ActivityManager.isHighEndGfx()) {
   14489                         pw.print(",high-end-gfx");
   14490                     }
   14491                     pw.println();
   14492                 }
   14493             }
   14494         }
   14495     }
   14496 
   14497     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
   14498             long memtrack, String name) {
   14499         sb.append("  ");
   14500         sb.append(ProcessList.makeOomAdjString(oomAdj));
   14501         sb.append(' ');
   14502         sb.append(ProcessList.makeProcStateString(procState));
   14503         sb.append(' ');
   14504         ProcessList.appendRamKb(sb, pss);
   14505         sb.append(" kB: ");
   14506         sb.append(name);
   14507         if (memtrack > 0) {
   14508             sb.append(" (");
   14509             sb.append(memtrack);
   14510             sb.append(" kB memtrack)");
   14511         }
   14512     }
   14513 
   14514     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
   14515         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
   14516         sb.append(" (pid ");
   14517         sb.append(mi.pid);
   14518         sb.append(") ");
   14519         sb.append(mi.adjType);
   14520         sb.append('\n');
   14521         if (mi.adjReason != null) {
   14522             sb.append("                      ");
   14523             sb.append(mi.adjReason);
   14524             sb.append('\n');
   14525         }
   14526     }
   14527 
   14528     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
   14529         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
   14530         for (int i=0, N=memInfos.size(); i<N; i++) {
   14531             ProcessMemInfo mi = memInfos.get(i);
   14532             infoMap.put(mi.pid, mi);
   14533         }
   14534         updateCpuStatsNow();
   14535         long[] memtrackTmp = new long[1];
   14536         synchronized (mProcessCpuTracker) {
   14537             final int N = mProcessCpuTracker.countStats();
   14538             for (int i=0; i<N; i++) {
   14539                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14540                 if (st.vsize > 0) {
   14541                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
   14542                     if (pss > 0) {
   14543                         if (infoMap.indexOfKey(st.pid) < 0) {
   14544                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   14545                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   14546                             mi.pss = pss;
   14547                             mi.memtrack = memtrackTmp[0];
   14548                             memInfos.add(mi);
   14549                         }
   14550                     }
   14551                 }
   14552             }
   14553         }
   14554 
   14555         long totalPss = 0;
   14556         long totalMemtrack = 0;
   14557         for (int i=0, N=memInfos.size(); i<N; i++) {
   14558             ProcessMemInfo mi = memInfos.get(i);
   14559             if (mi.pss == 0) {
   14560                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
   14561                 mi.memtrack = memtrackTmp[0];
   14562             }
   14563             totalPss += mi.pss;
   14564             totalMemtrack += mi.memtrack;
   14565         }
   14566         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   14567             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   14568                 if (lhs.oomAdj != rhs.oomAdj) {
   14569                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   14570                 }
   14571                 if (lhs.pss != rhs.pss) {
   14572                     return lhs.pss < rhs.pss ? 1 : -1;
   14573                 }
   14574                 return 0;
   14575             }
   14576         });
   14577 
   14578         StringBuilder tag = new StringBuilder(128);
   14579         StringBuilder stack = new StringBuilder(128);
   14580         tag.append("Low on memory -- ");
   14581         appendMemBucket(tag, totalPss, "total", false);
   14582         appendMemBucket(stack, totalPss, "total", true);
   14583 
   14584         StringBuilder fullNativeBuilder = new StringBuilder(1024);
   14585         StringBuilder shortNativeBuilder = new StringBuilder(1024);
   14586         StringBuilder fullJavaBuilder = new StringBuilder(1024);
   14587 
   14588         boolean firstLine = true;
   14589         int lastOomAdj = Integer.MIN_VALUE;
   14590         long extraNativeRam = 0;
   14591         long extraNativeMemtrack = 0;
   14592         long cachedPss = 0;
   14593         for (int i=0, N=memInfos.size(); i<N; i++) {
   14594             ProcessMemInfo mi = memInfos.get(i);
   14595 
   14596             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14597                 cachedPss += mi.pss;
   14598             }
   14599 
   14600             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   14601                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   14602                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   14603                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   14604                 if (lastOomAdj != mi.oomAdj) {
   14605                     lastOomAdj = mi.oomAdj;
   14606                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14607                         tag.append(" / ");
   14608                     }
   14609                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   14610                         if (firstLine) {
   14611                             stack.append(":");
   14612                             firstLine = false;
   14613                         }
   14614                         stack.append("\n\t at ");
   14615                     } else {
   14616                         stack.append("$");
   14617                     }
   14618                 } else {
   14619                     tag.append(" ");
   14620                     stack.append("$");
   14621                 }
   14622                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14623                     appendMemBucket(tag, mi.pss, mi.name, false);
   14624                 }
   14625                 appendMemBucket(stack, mi.pss, mi.name, true);
   14626                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   14627                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   14628                     stack.append("(");
   14629                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   14630                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   14631                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   14632                             stack.append(":");
   14633                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   14634                         }
   14635                     }
   14636                     stack.append(")");
   14637                 }
   14638             }
   14639 
   14640             appendMemInfo(fullNativeBuilder, mi);
   14641             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
   14642                 // The short form only has native processes that are >= 512K.
   14643                 if (mi.pss >= 512) {
   14644                     appendMemInfo(shortNativeBuilder, mi);
   14645                 } else {
   14646                     extraNativeRam += mi.pss;
   14647                     extraNativeMemtrack += mi.memtrack;
   14648                 }
   14649             } else {
   14650                 // Short form has all other details, but if we have collected RAM
   14651                 // from smaller native processes let's dump a summary of that.
   14652                 if (extraNativeRam > 0) {
   14653                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
   14654                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
   14655                     shortNativeBuilder.append('\n');
   14656                     extraNativeRam = 0;
   14657                 }
   14658                 appendMemInfo(fullJavaBuilder, mi);
   14659             }
   14660         }
   14661 
   14662         fullJavaBuilder.append("           ");
   14663         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
   14664         fullJavaBuilder.append(" kB: TOTAL");
   14665         if (totalMemtrack > 0) {
   14666             fullJavaBuilder.append(" (");
   14667             fullJavaBuilder.append(totalMemtrack);
   14668             fullJavaBuilder.append(" kB memtrack)");
   14669         } else {
   14670         }
   14671         fullJavaBuilder.append("\n");
   14672 
   14673         MemInfoReader memInfo = new MemInfoReader();
   14674         memInfo.readMemInfo();
   14675         final long[] infos = memInfo.getRawInfo();
   14676 
   14677         StringBuilder memInfoBuilder = new StringBuilder(1024);
   14678         Debug.getMemInfo(infos);
   14679         memInfoBuilder.append("  MemInfo: ");
   14680         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
   14681         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
   14682         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
   14683         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
   14684         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
   14685         memInfoBuilder.append("           ");
   14686         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
   14687         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
   14688         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
   14689         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
   14690         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   14691             memInfoBuilder.append("  ZRAM: ");
   14692             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
   14693             memInfoBuilder.append(" kB RAM, ");
   14694             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
   14695             memInfoBuilder.append(" kB swap total, ");
   14696             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
   14697             memInfoBuilder.append(" kB swap free\n");
   14698         }
   14699         final long[] ksm = getKsmInfo();
   14700         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
   14701                 || ksm[KSM_VOLATILE] != 0) {
   14702             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
   14703             memInfoBuilder.append(" kB saved from shared ");
   14704             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
   14705             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
   14706             memInfoBuilder.append(" kB unshared; ");
   14707             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
   14708         }
   14709         memInfoBuilder.append("  Free RAM: ");
   14710         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
   14711                 + memInfo.getFreeSizeKb());
   14712         memInfoBuilder.append(" kB\n");
   14713         memInfoBuilder.append("  Used RAM: ");
   14714         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
   14715         memInfoBuilder.append(" kB\n");
   14716         memInfoBuilder.append("  Lost RAM: ");
   14717         memInfoBuilder.append(memInfo.getTotalSizeKb()
   14718                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   14719                 - memInfo.getKernelUsedSizeKb());
   14720         memInfoBuilder.append(" kB\n");
   14721         Slog.i(TAG, "Low on memory:");
   14722         Slog.i(TAG, shortNativeBuilder.toString());
   14723         Slog.i(TAG, fullJavaBuilder.toString());
   14724         Slog.i(TAG, memInfoBuilder.toString());
   14725 
   14726         StringBuilder dropBuilder = new StringBuilder(1024);
   14727         /*
   14728         StringWriter oomSw = new StringWriter();
   14729         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   14730         StringWriter catSw = new StringWriter();
   14731         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   14732         String[] emptyArgs = new String[] { };
   14733         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   14734         oomPw.flush();
   14735         String oomString = oomSw.toString();
   14736         */
   14737         dropBuilder.append("Low on memory:");
   14738         dropBuilder.append(stack);
   14739         dropBuilder.append('\n');
   14740         dropBuilder.append(fullNativeBuilder);
   14741         dropBuilder.append(fullJavaBuilder);
   14742         dropBuilder.append('\n');
   14743         dropBuilder.append(memInfoBuilder);
   14744         dropBuilder.append('\n');
   14745         /*
   14746         dropBuilder.append(oomString);
   14747         dropBuilder.append('\n');
   14748         */
   14749         StringWriter catSw = new StringWriter();
   14750         synchronized (ActivityManagerService.this) {
   14751             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   14752             String[] emptyArgs = new String[] { };
   14753             catPw.println();
   14754             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   14755             catPw.println();
   14756             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   14757                     false, false, null);
   14758             catPw.println();
   14759             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   14760             catPw.flush();
   14761         }
   14762         dropBuilder.append(catSw.toString());
   14763         addErrorToDropBox("lowmem", null, "system_server", null,
   14764                 null, tag.toString(), dropBuilder.toString(), null, null);
   14765         //Slog.i(TAG, "Sent to dropbox:");
   14766         //Slog.i(TAG, dropBuilder.toString());
   14767         synchronized (ActivityManagerService.this) {
   14768             long now = SystemClock.uptimeMillis();
   14769             if (mLastMemUsageReportTime < now) {
   14770                 mLastMemUsageReportTime = now;
   14771             }
   14772         }
   14773     }
   14774 
   14775     /**
   14776      * Searches array of arguments for the specified string
   14777      * @param args array of argument strings
   14778      * @param value value to search for
   14779      * @return true if the value is contained in the array
   14780      */
   14781     private static boolean scanArgs(String[] args, String value) {
   14782         if (args != null) {
   14783             for (String arg : args) {
   14784                 if (value.equals(arg)) {
   14785                     return true;
   14786                 }
   14787             }
   14788         }
   14789         return false;
   14790     }
   14791 
   14792     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   14793             ContentProviderRecord cpr, boolean always) {
   14794         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   14795 
   14796         if (!inLaunching || always) {
   14797             synchronized (cpr) {
   14798                 cpr.launchingApp = null;
   14799                 cpr.notifyAll();
   14800             }
   14801             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   14802             String names[] = cpr.info.authority.split(";");
   14803             for (int j = 0; j < names.length; j++) {
   14804                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   14805             }
   14806         }
   14807 
   14808         for (int i=0; i<cpr.connections.size(); i++) {
   14809             ContentProviderConnection conn = cpr.connections.get(i);
   14810             if (conn.waiting) {
   14811                 // If this connection is waiting for the provider, then we don't
   14812                 // need to mess with its process unless we are always removing
   14813                 // or for some reason the provider is not currently launching.
   14814                 if (inLaunching && !always) {
   14815                     continue;
   14816                 }
   14817             }
   14818             ProcessRecord capp = conn.client;
   14819             conn.dead = true;
   14820             if (conn.stableCount > 0) {
   14821                 if (!capp.persistent && capp.thread != null
   14822                         && capp.pid != 0
   14823                         && capp.pid != MY_PID) {
   14824                     capp.kill("depends on provider "
   14825                             + cpr.name.flattenToShortString()
   14826                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
   14827                 }
   14828             } else if (capp.thread != null && conn.provider.provider != null) {
   14829                 try {
   14830                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   14831                 } catch (RemoteException e) {
   14832                 }
   14833                 // In the protocol here, we don't expect the client to correctly
   14834                 // clean up this connection, we'll just remove it.
   14835                 cpr.connections.remove(i);
   14836                 if (conn.client.conProviders.remove(conn)) {
   14837                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
   14838                 }
   14839             }
   14840         }
   14841 
   14842         if (inLaunching && always) {
   14843             mLaunchingProviders.remove(cpr);
   14844         }
   14845         return inLaunching;
   14846     }
   14847 
   14848     /**
   14849      * Main code for cleaning up a process when it has gone away.  This is
   14850      * called both as a result of the process dying, or directly when stopping
   14851      * a process when running in single process mode.
   14852      *
   14853      * @return Returns true if the given process has been restarted, so the
   14854      * app that was passed in must remain on the process lists.
   14855      */
   14856     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   14857             boolean restarting, boolean allowRestart, int index) {
   14858         if (index >= 0) {
   14859             removeLruProcessLocked(app);
   14860             ProcessList.remove(app.pid);
   14861         }
   14862 
   14863         mProcessesToGc.remove(app);
   14864         mPendingPssProcesses.remove(app);
   14865 
   14866         // Dismiss any open dialogs.
   14867         if (app.crashDialog != null && !app.forceCrashReport) {
   14868             app.crashDialog.dismiss();
   14869             app.crashDialog = null;
   14870         }
   14871         if (app.anrDialog != null) {
   14872             app.anrDialog.dismiss();
   14873             app.anrDialog = null;
   14874         }
   14875         if (app.waitDialog != null) {
   14876             app.waitDialog.dismiss();
   14877             app.waitDialog = null;
   14878         }
   14879 
   14880         app.crashing = false;
   14881         app.notResponding = false;
   14882 
   14883         app.resetPackageList(mProcessStats);
   14884         app.unlinkDeathRecipient();
   14885         app.makeInactive(mProcessStats);
   14886         app.waitingToKill = null;
   14887         app.forcingToForeground = null;
   14888         updateProcessForegroundLocked(app, false, false);
   14889         app.foregroundActivities = false;
   14890         app.hasShownUi = false;
   14891         app.treatLikeActivity = false;
   14892         app.hasAboveClient = false;
   14893         app.hasClientActivities = false;
   14894 
   14895         mServices.killServicesLocked(app, allowRestart);
   14896 
   14897         boolean restart = false;
   14898 
   14899         // Remove published content providers.
   14900         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   14901             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   14902             final boolean always = app.bad || !allowRestart;
   14903             if (removeDyingProviderLocked(app, cpr, always) || always) {
   14904                 // We left the provider in the launching list, need to
   14905                 // restart it.
   14906                 restart = true;
   14907             }
   14908 
   14909             cpr.provider = null;
   14910             cpr.proc = null;
   14911         }
   14912         app.pubProviders.clear();
   14913 
   14914         // Take care of any launching providers waiting for this process.
   14915         if (checkAppInLaunchingProvidersLocked(app, false)) {
   14916             restart = true;
   14917         }
   14918 
   14919         // Unregister from connected content providers.
   14920         if (!app.conProviders.isEmpty()) {
   14921             for (int i=0; i<app.conProviders.size(); i++) {
   14922                 ContentProviderConnection conn = app.conProviders.get(i);
   14923                 conn.provider.connections.remove(conn);
   14924                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
   14925                         conn.provider.name);
   14926             }
   14927             app.conProviders.clear();
   14928         }
   14929 
   14930         // At this point there may be remaining entries in mLaunchingProviders
   14931         // where we were the only one waiting, so they are no longer of use.
   14932         // Look for these and clean up if found.
   14933         // XXX Commented out for now.  Trying to figure out a way to reproduce
   14934         // the actual situation to identify what is actually going on.
   14935         if (false) {
   14936             for (int i=0; i<mLaunchingProviders.size(); i++) {
   14937                 ContentProviderRecord cpr = (ContentProviderRecord)
   14938                         mLaunchingProviders.get(i);
   14939                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   14940                     synchronized (cpr) {
   14941                         cpr.launchingApp = null;
   14942                         cpr.notifyAll();
   14943                     }
   14944                 }
   14945             }
   14946         }
   14947 
   14948         skipCurrentReceiverLocked(app);
   14949 
   14950         // Unregister any receivers.
   14951         for (int i=app.receivers.size()-1; i>=0; i--) {
   14952             removeReceiverLocked(app.receivers.valueAt(i));
   14953         }
   14954         app.receivers.clear();
   14955 
   14956         // If the app is undergoing backup, tell the backup manager about it
   14957         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   14958             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   14959                     + mBackupTarget.appInfo + " died during backup");
   14960             try {
   14961                 IBackupManager bm = IBackupManager.Stub.asInterface(
   14962                         ServiceManager.getService(Context.BACKUP_SERVICE));
   14963                 bm.agentDisconnected(app.info.packageName);
   14964             } catch (RemoteException e) {
   14965                 // can't happen; backup manager is local
   14966             }
   14967         }
   14968 
   14969         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   14970             ProcessChangeItem item = mPendingProcessChanges.get(i);
   14971             if (item.pid == app.pid) {
   14972                 mPendingProcessChanges.remove(i);
   14973                 mAvailProcessChanges.add(item);
   14974             }
   14975         }
   14976         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   14977 
   14978         // If the caller is restarting this app, then leave it in its
   14979         // current lists and let the caller take care of it.
   14980         if (restarting) {
   14981             return false;
   14982         }
   14983 
   14984         if (!app.persistent || app.isolated) {
   14985             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   14986                     "Removing non-persistent process during cleanup: " + app);
   14987             mProcessNames.remove(app.processName, app.uid);
   14988             mIsolatedProcesses.remove(app.uid);
   14989             if (mHeavyWeightProcess == app) {
   14990                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   14991                         mHeavyWeightProcess.userId, 0));
   14992                 mHeavyWeightProcess = null;
   14993             }
   14994         } else if (!app.removed) {
   14995             // This app is persistent, so we need to keep its record around.
   14996             // If it is not already on the pending app list, add it there
   14997             // and start a new process for it.
   14998             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   14999                 mPersistentStartingProcesses.add(app);
   15000                 restart = true;
   15001             }
   15002         }
   15003         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   15004                 "Clean-up removing on hold: " + app);
   15005         mProcessesOnHold.remove(app);
   15006 
   15007         if (app == mHomeProcess) {
   15008             mHomeProcess = null;
   15009         }
   15010         if (app == mPreviousProcess) {
   15011             mPreviousProcess = null;
   15012         }
   15013 
   15014         if (restart && !app.isolated) {
   15015             // We have components that still need to be running in the
   15016             // process, so re-launch it.
   15017             if (index < 0) {
   15018                 ProcessList.remove(app.pid);
   15019             }
   15020             mProcessNames.put(app.processName, app.uid, app);
   15021             startProcessLocked(app, "restart", app.processName);
   15022             return true;
   15023         } else if (app.pid > 0 && app.pid != MY_PID) {
   15024             // Goodbye!
   15025             boolean removed;
   15026             synchronized (mPidsSelfLocked) {
   15027                 mPidsSelfLocked.remove(app.pid);
   15028                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   15029             }
   15030             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   15031             if (app.isolated) {
   15032                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   15033             }
   15034             app.setPid(0);
   15035         }
   15036         return false;
   15037     }
   15038 
   15039     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   15040         // Look through the content providers we are waiting to have launched,
   15041         // and if any run in this process then either schedule a restart of
   15042         // the process or kill the client waiting for it if this process has
   15043         // gone bad.
   15044         int NL = mLaunchingProviders.size();
   15045         boolean restart = false;
   15046         for (int i=0; i<NL; i++) {
   15047             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   15048             if (cpr.launchingApp == app) {
   15049                 if (!alwaysBad && !app.bad) {
   15050                     restart = true;
   15051                 } else {
   15052                     removeDyingProviderLocked(app, cpr, true);
   15053                     // cpr should have been removed from mLaunchingProviders
   15054                     NL = mLaunchingProviders.size();
   15055                     i--;
   15056                 }
   15057             }
   15058         }
   15059         return restart;
   15060     }
   15061 
   15062     // =========================================================
   15063     // SERVICES
   15064     // =========================================================
   15065 
   15066     @Override
   15067     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   15068             int flags) {
   15069         enforceNotIsolatedCaller("getServices");
   15070         synchronized (this) {
   15071             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   15072         }
   15073     }
   15074 
   15075     @Override
   15076     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   15077         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   15078         synchronized (this) {
   15079             return mServices.getRunningServiceControlPanelLocked(name);
   15080         }
   15081     }
   15082 
   15083     @Override
   15084     public ComponentName startService(IApplicationThread caller, Intent service,
   15085             String resolvedType, int userId) {
   15086         enforceNotIsolatedCaller("startService");
   15087         // Refuse possible leaked file descriptors
   15088         if (service != null && service.hasFileDescriptors() == true) {
   15089             throw new IllegalArgumentException("File descriptors passed in Intent");
   15090         }
   15091 
   15092         if (DEBUG_SERVICE)
   15093             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   15094         synchronized(this) {
   15095             final int callingPid = Binder.getCallingPid();
   15096             final int callingUid = Binder.getCallingUid();
   15097             final long origId = Binder.clearCallingIdentity();
   15098             ComponentName res = mServices.startServiceLocked(caller, service,
   15099                     resolvedType, callingPid, callingUid, userId);
   15100             Binder.restoreCallingIdentity(origId);
   15101             return res;
   15102         }
   15103     }
   15104 
   15105     ComponentName startServiceInPackage(int uid,
   15106             Intent service, String resolvedType, int userId) {
   15107         synchronized(this) {
   15108             if (DEBUG_SERVICE)
   15109                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   15110             final long origId = Binder.clearCallingIdentity();
   15111             ComponentName res = mServices.startServiceLocked(null, service,
   15112                     resolvedType, -1, uid, userId);
   15113             Binder.restoreCallingIdentity(origId);
   15114             return res;
   15115         }
   15116     }
   15117 
   15118     @Override
   15119     public int stopService(IApplicationThread caller, Intent service,
   15120             String resolvedType, int userId) {
   15121         enforceNotIsolatedCaller("stopService");
   15122         // Refuse possible leaked file descriptors
   15123         if (service != null && service.hasFileDescriptors() == true) {
   15124             throw new IllegalArgumentException("File descriptors passed in Intent");
   15125         }
   15126 
   15127         synchronized(this) {
   15128             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   15129         }
   15130     }
   15131 
   15132     @Override
   15133     public IBinder peekService(Intent service, String resolvedType) {
   15134         enforceNotIsolatedCaller("peekService");
   15135         // Refuse possible leaked file descriptors
   15136         if (service != null && service.hasFileDescriptors() == true) {
   15137             throw new IllegalArgumentException("File descriptors passed in Intent");
   15138         }
   15139         synchronized(this) {
   15140             return mServices.peekServiceLocked(service, resolvedType);
   15141         }
   15142     }
   15143 
   15144     @Override
   15145     public boolean stopServiceToken(ComponentName className, IBinder token,
   15146             int startId) {
   15147         synchronized(this) {
   15148             return mServices.stopServiceTokenLocked(className, token, startId);
   15149         }
   15150     }
   15151 
   15152     @Override
   15153     public void setServiceForeground(ComponentName className, IBinder token,
   15154             int id, Notification notification, boolean removeNotification) {
   15155         synchronized(this) {
   15156             mServices.setServiceForegroundLocked(className, token, id, notification,
   15157                     removeNotification);
   15158         }
   15159     }
   15160 
   15161     @Override
   15162     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   15163             boolean requireFull, String name, String callerPackage) {
   15164         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
   15165                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   15166     }
   15167 
   15168     int unsafeConvertIncomingUser(int userId) {
   15169         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
   15170                 ? mCurrentUserId : userId;
   15171     }
   15172 
   15173     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   15174             int allowMode, String name, String callerPackage) {
   15175         final int callingUserId = UserHandle.getUserId(callingUid);
   15176         if (callingUserId == userId) {
   15177             return userId;
   15178         }
   15179 
   15180         // Note that we may be accessing mCurrentUserId outside of a lock...
   15181         // shouldn't be a big deal, if this is being called outside
   15182         // of a locked context there is intrinsically a race with
   15183         // the value the caller will receive and someone else changing it.
   15184         // We assume that USER_CURRENT_OR_SELF will use the current user; later
   15185         // we will switch to the calling user if access to the current user fails.
   15186         int targetUserId = unsafeConvertIncomingUser(userId);
   15187 
   15188         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   15189             final boolean allow;
   15190             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   15191                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   15192                 // If the caller has this permission, they always pass go.  And collect $200.
   15193                 allow = true;
   15194             } else if (allowMode == ALLOW_FULL_ONLY) {
   15195                 // We require full access, sucks to be you.
   15196                 allow = false;
   15197             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   15198                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
   15199                 // If the caller does not have either permission, they are always doomed.
   15200                 allow = false;
   15201             } else if (allowMode == ALLOW_NON_FULL) {
   15202                 // We are blanket allowing non-full access, you lucky caller!
   15203                 allow = true;
   15204             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
   15205                 // We may or may not allow this depending on whether the two users are
   15206                 // in the same profile.
   15207                 synchronized (mUserProfileGroupIdsSelfLocked) {
   15208                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
   15209                             UserInfo.NO_PROFILE_GROUP_ID);
   15210                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
   15211                             UserInfo.NO_PROFILE_GROUP_ID);
   15212                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
   15213                             && callingProfile == targetProfile;
   15214                 }
   15215             } else {
   15216                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
   15217             }
   15218             if (!allow) {
   15219                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   15220                     // In this case, they would like to just execute as their
   15221                     // owner user instead of failing.
   15222                     targetUserId = callingUserId;
   15223                 } else {
   15224                     StringBuilder builder = new StringBuilder(128);
   15225                     builder.append("Permission Denial: ");
   15226                     builder.append(name);
   15227                     if (callerPackage != null) {
   15228                         builder.append(" from ");
   15229                         builder.append(callerPackage);
   15230                     }
   15231                     builder.append(" asks to run as user ");
   15232                     builder.append(userId);
   15233                     builder.append(" but is calling from user ");
   15234                     builder.append(UserHandle.getUserId(callingUid));
   15235                     builder.append("; this requires ");
   15236                     builder.append(INTERACT_ACROSS_USERS_FULL);
   15237                     if (allowMode != ALLOW_FULL_ONLY) {
   15238                         builder.append(" or ");
   15239                         builder.append(INTERACT_ACROSS_USERS);
   15240                     }
   15241                     String msg = builder.toString();
   15242                     Slog.w(TAG, msg);
   15243                     throw new SecurityException(msg);
   15244                 }
   15245             }
   15246         }
   15247         if (!allowAll && targetUserId < 0) {
   15248             throw new IllegalArgumentException(
   15249                     "Call does not support special user #" + targetUserId);
   15250         }
   15251         // Check shell permission
   15252         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
   15253             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
   15254                     targetUserId)) {
   15255                 throw new SecurityException("Shell does not have permission to access user "
   15256                         + targetUserId + "\n " + Debug.getCallers(3));
   15257             }
   15258         }
   15259         return targetUserId;
   15260     }
   15261 
   15262     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   15263             String className, int flags) {
   15264         boolean result = false;
   15265         // For apps that don't have pre-defined UIDs, check for permission
   15266         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   15267             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   15268                 if (ActivityManager.checkUidPermission(
   15269                         INTERACT_ACROSS_USERS,
   15270                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   15271                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   15272                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   15273                             + " requests FLAG_SINGLE_USER, but app does not hold "
   15274                             + INTERACT_ACROSS_USERS;
   15275                     Slog.w(TAG, msg);
   15276                     throw new SecurityException(msg);
   15277                 }
   15278                 // Permission passed
   15279                 result = true;
   15280             }
   15281         } else if ("system".equals(componentProcessName)) {
   15282             result = true;
   15283         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   15284             // Phone app and persistent apps are allowed to export singleuser providers.
   15285             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   15286                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   15287         }
   15288         if (DEBUG_MU) {
   15289             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   15290                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   15291         }
   15292         return result;
   15293     }
   15294 
   15295     /**
   15296      * Checks to see if the caller is in the same app as the singleton
   15297      * component, or the component is in a special app. It allows special apps
   15298      * to export singleton components but prevents exporting singleton
   15299      * components for regular apps.
   15300      */
   15301     boolean isValidSingletonCall(int callingUid, int componentUid) {
   15302         int componentAppId = UserHandle.getAppId(componentUid);
   15303         return UserHandle.isSameApp(callingUid, componentUid)
   15304                 || componentAppId == Process.SYSTEM_UID
   15305                 || componentAppId == Process.PHONE_UID
   15306                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   15307                         == PackageManager.PERMISSION_GRANTED;
   15308     }
   15309 
   15310     public int bindService(IApplicationThread caller, IBinder token,
   15311             Intent service, String resolvedType,
   15312             IServiceConnection connection, int flags, int userId) {
   15313         enforceNotIsolatedCaller("bindService");
   15314 
   15315         // Refuse possible leaked file descriptors
   15316         if (service != null && service.hasFileDescriptors() == true) {
   15317             throw new IllegalArgumentException("File descriptors passed in Intent");
   15318         }
   15319 
   15320         synchronized(this) {
   15321             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   15322                     connection, flags, userId);
   15323         }
   15324     }
   15325 
   15326     public boolean unbindService(IServiceConnection connection) {
   15327         synchronized (this) {
   15328             return mServices.unbindServiceLocked(connection);
   15329         }
   15330     }
   15331 
   15332     public void publishService(IBinder token, Intent intent, IBinder service) {
   15333         // Refuse possible leaked file descriptors
   15334         if (intent != null && intent.hasFileDescriptors() == true) {
   15335             throw new IllegalArgumentException("File descriptors passed in Intent");
   15336         }
   15337 
   15338         synchronized(this) {
   15339             if (!(token instanceof ServiceRecord)) {
   15340                 throw new IllegalArgumentException("Invalid service token");
   15341             }
   15342             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   15343         }
   15344     }
   15345 
   15346     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   15347         // Refuse possible leaked file descriptors
   15348         if (intent != null && intent.hasFileDescriptors() == true) {
   15349             throw new IllegalArgumentException("File descriptors passed in Intent");
   15350         }
   15351 
   15352         synchronized(this) {
   15353             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   15354         }
   15355     }
   15356 
   15357     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   15358         synchronized(this) {
   15359             if (!(token instanceof ServiceRecord)) {
   15360                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
   15361                 throw new IllegalArgumentException("Invalid service token");
   15362             }
   15363             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   15364         }
   15365     }
   15366 
   15367     // =========================================================
   15368     // BACKUP AND RESTORE
   15369     // =========================================================
   15370 
   15371     // Cause the target app to be launched if necessary and its backup agent
   15372     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   15373     // activity manager to announce its creation.
   15374     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   15375         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   15376         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   15377 
   15378         synchronized(this) {
   15379             // !!! TODO: currently no check here that we're already bound
   15380             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   15381             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15382             synchronized (stats) {
   15383                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   15384             }
   15385 
   15386             // Backup agent is now in use, its package can't be stopped.
   15387             try {
   15388                 AppGlobals.getPackageManager().setPackageStoppedState(
   15389                         app.packageName, false, UserHandle.getUserId(app.uid));
   15390             } catch (RemoteException e) {
   15391             } catch (IllegalArgumentException e) {
   15392                 Slog.w(TAG, "Failed trying to unstop package "
   15393                         + app.packageName + ": " + e);
   15394             }
   15395 
   15396             BackupRecord r = new BackupRecord(ss, app, backupMode);
   15397             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   15398                     ? new ComponentName(app.packageName, app.backupAgentName)
   15399                     : new ComponentName("android", "FullBackupAgent");
   15400             // startProcessLocked() returns existing proc's record if it's already running
   15401             ProcessRecord proc = startProcessLocked(app.processName, app,
   15402                     false, 0, "backup", hostingName, false, false, false);
   15403             if (proc == null) {
   15404                 Slog.e(TAG, "Unable to start backup agent process " + r);
   15405                 return false;
   15406             }
   15407 
   15408             r.app = proc;
   15409             mBackupTarget = r;
   15410             mBackupAppName = app.packageName;
   15411 
   15412             // Try not to kill the process during backup
   15413             updateOomAdjLocked(proc);
   15414 
   15415             // If the process is already attached, schedule the creation of the backup agent now.
   15416             // If it is not yet live, this will be done when it attaches to the framework.
   15417             if (proc.thread != null) {
   15418                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   15419                 try {
   15420                     proc.thread.scheduleCreateBackupAgent(app,
   15421                             compatibilityInfoForPackageLocked(app), backupMode);
   15422                 } catch (RemoteException e) {
   15423                     // Will time out on the backup manager side
   15424                 }
   15425             } else {
   15426                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   15427             }
   15428             // Invariants: at this point, the target app process exists and the application
   15429             // is either already running or in the process of coming up.  mBackupTarget and
   15430             // mBackupAppName describe the app, so that when it binds back to the AM we
   15431             // know that it's scheduled for a backup-agent operation.
   15432         }
   15433 
   15434         return true;
   15435     }
   15436 
   15437     @Override
   15438     public void clearPendingBackup() {
   15439         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   15440         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   15441 
   15442         synchronized (this) {
   15443             mBackupTarget = null;
   15444             mBackupAppName = null;
   15445         }
   15446     }
   15447 
   15448     // A backup agent has just come up
   15449     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   15450         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   15451                 + " = " + agent);
   15452 
   15453         synchronized(this) {
   15454             if (!agentPackageName.equals(mBackupAppName)) {
   15455                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   15456                 return;
   15457             }
   15458         }
   15459 
   15460         long oldIdent = Binder.clearCallingIdentity();
   15461         try {
   15462             IBackupManager bm = IBackupManager.Stub.asInterface(
   15463                     ServiceManager.getService(Context.BACKUP_SERVICE));
   15464             bm.agentConnected(agentPackageName, agent);
   15465         } catch (RemoteException e) {
   15466             // can't happen; the backup manager service is local
   15467         } catch (Exception e) {
   15468             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   15469             e.printStackTrace();
   15470         } finally {
   15471             Binder.restoreCallingIdentity(oldIdent);
   15472         }
   15473     }
   15474 
   15475     // done with this agent
   15476     public void unbindBackupAgent(ApplicationInfo appInfo) {
   15477         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   15478         if (appInfo == null) {
   15479             Slog.w(TAG, "unbind backup agent for null app");
   15480             return;
   15481         }
   15482 
   15483         synchronized(this) {
   15484             try {
   15485                 if (mBackupAppName == null) {
   15486                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   15487                     return;
   15488                 }
   15489 
   15490                 if (!mBackupAppName.equals(appInfo.packageName)) {
   15491                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   15492                     return;
   15493                 }
   15494 
   15495                 // Not backing this app up any more; reset its OOM adjustment
   15496                 final ProcessRecord proc = mBackupTarget.app;
   15497                 updateOomAdjLocked(proc);
   15498 
   15499                 // If the app crashed during backup, 'thread' will be null here
   15500                 if (proc.thread != null) {
   15501                     try {
   15502                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   15503                                 compatibilityInfoForPackageLocked(appInfo));
   15504                     } catch (Exception e) {
   15505                         Slog.e(TAG, "Exception when unbinding backup agent:");
   15506                         e.printStackTrace();
   15507                     }
   15508                 }
   15509             } finally {
   15510                 mBackupTarget = null;
   15511                 mBackupAppName = null;
   15512             }
   15513         }
   15514     }
   15515     // =========================================================
   15516     // BROADCASTS
   15517     // =========================================================
   15518 
   15519     private final List getStickiesLocked(String action, IntentFilter filter,
   15520             List cur, int userId) {
   15521         final ContentResolver resolver = mContext.getContentResolver();
   15522         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   15523         if (stickies == null) {
   15524             return cur;
   15525         }
   15526         final ArrayList<Intent> list = stickies.get(action);
   15527         if (list == null) {
   15528             return cur;
   15529         }
   15530         int N = list.size();
   15531         for (int i=0; i<N; i++) {
   15532             Intent intent = list.get(i);
   15533             if (filter.match(resolver, intent, true, TAG) >= 0) {
   15534                 if (cur == null) {
   15535                     cur = new ArrayList<Intent>();
   15536                 }
   15537                 cur.add(intent);
   15538             }
   15539         }
   15540         return cur;
   15541     }
   15542 
   15543     boolean isPendingBroadcastProcessLocked(int pid) {
   15544         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   15545                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   15546     }
   15547 
   15548     void skipPendingBroadcastLocked(int pid) {
   15549             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   15550             for (BroadcastQueue queue : mBroadcastQueues) {
   15551                 queue.skipPendingBroadcastLocked(pid);
   15552             }
   15553     }
   15554 
   15555     // The app just attached; send any pending broadcasts that it should receive
   15556     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   15557         boolean didSomething = false;
   15558         for (BroadcastQueue queue : mBroadcastQueues) {
   15559             didSomething |= queue.sendPendingBroadcastsLocked(app);
   15560         }
   15561         return didSomething;
   15562     }
   15563 
   15564     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   15565             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   15566         enforceNotIsolatedCaller("registerReceiver");
   15567         int callingUid;
   15568         int callingPid;
   15569         synchronized(this) {
   15570             ProcessRecord callerApp = null;
   15571             if (caller != null) {
   15572                 callerApp = getRecordForAppLocked(caller);
   15573                 if (callerApp == null) {
   15574                     throw new SecurityException(
   15575                             "Unable to find app for caller " + caller
   15576                             + " (pid=" + Binder.getCallingPid()
   15577                             + ") when registering receiver " + receiver);
   15578                 }
   15579                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   15580                         !callerApp.pkgList.containsKey(callerPackage) &&
   15581                         !"android".equals(callerPackage)) {
   15582                     throw new SecurityException("Given caller package " + callerPackage
   15583                             + " is not running in process " + callerApp);
   15584                 }
   15585                 callingUid = callerApp.info.uid;
   15586                 callingPid = callerApp.pid;
   15587             } else {
   15588                 callerPackage = null;
   15589                 callingUid = Binder.getCallingUid();
   15590                 callingPid = Binder.getCallingPid();
   15591             }
   15592 
   15593             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   15594                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   15595 
   15596             List allSticky = null;
   15597 
   15598             // Look for any matching sticky broadcasts...
   15599             Iterator actions = filter.actionsIterator();
   15600             if (actions != null) {
   15601                 while (actions.hasNext()) {
   15602                     String action = (String)actions.next();
   15603                     allSticky = getStickiesLocked(action, filter, allSticky,
   15604                             UserHandle.USER_ALL);
   15605                     allSticky = getStickiesLocked(action, filter, allSticky,
   15606                             UserHandle.getUserId(callingUid));
   15607                 }
   15608             } else {
   15609                 allSticky = getStickiesLocked(null, filter, allSticky,
   15610                         UserHandle.USER_ALL);
   15611                 allSticky = getStickiesLocked(null, filter, allSticky,
   15612                         UserHandle.getUserId(callingUid));
   15613             }
   15614 
   15615             // The first sticky in the list is returned directly back to
   15616             // the client.
   15617             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   15618 
   15619             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   15620                     + ": " + sticky);
   15621 
   15622             if (receiver == null) {
   15623                 return sticky;
   15624             }
   15625 
   15626             ReceiverList rl
   15627                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   15628             if (rl == null) {
   15629                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   15630                         userId, receiver);
   15631                 if (rl.app != null) {
   15632                     rl.app.receivers.add(rl);
   15633                 } else {
   15634                     try {
   15635                         receiver.asBinder().linkToDeath(rl, 0);
   15636                     } catch (RemoteException e) {
   15637                         return sticky;
   15638                     }
   15639                     rl.linkedToDeath = true;
   15640                 }
   15641                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   15642             } else if (rl.uid != callingUid) {
   15643                 throw new IllegalArgumentException(
   15644                         "Receiver requested to register for uid " + callingUid
   15645                         + " was previously registered for uid " + rl.uid);
   15646             } else if (rl.pid != callingPid) {
   15647                 throw new IllegalArgumentException(
   15648                         "Receiver requested to register for pid " + callingPid
   15649                         + " was previously registered for pid " + rl.pid);
   15650             } else if (rl.userId != userId) {
   15651                 throw new IllegalArgumentException(
   15652                         "Receiver requested to register for user " + userId
   15653                         + " was previously registered for user " + rl.userId);
   15654             }
   15655             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   15656                     permission, callingUid, userId);
   15657             rl.add(bf);
   15658             if (!bf.debugCheck()) {
   15659                 Slog.w(TAG, "==> For Dynamic broadast");
   15660             }
   15661             mReceiverResolver.addFilter(bf);
   15662 
   15663             // Enqueue broadcasts for all existing stickies that match
   15664             // this filter.
   15665             if (allSticky != null) {
   15666                 ArrayList receivers = new ArrayList();
   15667                 receivers.add(bf);
   15668 
   15669                 int N = allSticky.size();
   15670                 for (int i=0; i<N; i++) {
   15671                     Intent intent = (Intent)allSticky.get(i);
   15672                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   15673                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   15674                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   15675                             null, null, false, true, true, -1);
   15676                     queue.enqueueParallelBroadcastLocked(r);
   15677                     queue.scheduleBroadcastsLocked();
   15678                 }
   15679             }
   15680 
   15681             return sticky;
   15682         }
   15683     }
   15684 
   15685     public void unregisterReceiver(IIntentReceiver receiver) {
   15686         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   15687 
   15688         final long origId = Binder.clearCallingIdentity();
   15689         try {
   15690             boolean doTrim = false;
   15691 
   15692             synchronized(this) {
   15693                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   15694                 if (rl != null) {
   15695                     if (rl.curBroadcast != null) {
   15696                         BroadcastRecord r = rl.curBroadcast;
   15697                         final boolean doNext = finishReceiverLocked(
   15698                                 receiver.asBinder(), r.resultCode, r.resultData,
   15699                                 r.resultExtras, r.resultAbort);
   15700                         if (doNext) {
   15701                             doTrim = true;
   15702                             r.queue.processNextBroadcast(false);
   15703                         }
   15704                     }
   15705 
   15706                     if (rl.app != null) {
   15707                         rl.app.receivers.remove(rl);
   15708                     }
   15709                     removeReceiverLocked(rl);
   15710                     if (rl.linkedToDeath) {
   15711                         rl.linkedToDeath = false;
   15712                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   15713                     }
   15714                 }
   15715             }
   15716 
   15717             // If we actually concluded any broadcasts, we might now be able
   15718             // to trim the recipients' apps from our working set
   15719             if (doTrim) {
   15720                 trimApplications();
   15721                 return;
   15722             }
   15723 
   15724         } finally {
   15725             Binder.restoreCallingIdentity(origId);
   15726         }
   15727     }
   15728 
   15729     void removeReceiverLocked(ReceiverList rl) {
   15730         mRegisteredReceivers.remove(rl.receiver.asBinder());
   15731         int N = rl.size();
   15732         for (int i=0; i<N; i++) {
   15733             mReceiverResolver.removeFilter(rl.get(i));
   15734         }
   15735     }
   15736 
   15737     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   15738         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15739             ProcessRecord r = mLruProcesses.get(i);
   15740             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   15741                 try {
   15742                     r.thread.dispatchPackageBroadcast(cmd, packages);
   15743                 } catch (RemoteException ex) {
   15744                 }
   15745             }
   15746         }
   15747     }
   15748 
   15749     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   15750             int callingUid, int[] users) {
   15751         List<ResolveInfo> receivers = null;
   15752         try {
   15753             HashSet<ComponentName> singleUserReceivers = null;
   15754             boolean scannedFirstReceivers = false;
   15755             for (int user : users) {
   15756                 // Skip users that have Shell restrictions
   15757                 if (callingUid == Process.SHELL_UID
   15758                         && getUserManagerLocked().hasUserRestriction(
   15759                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
   15760                     continue;
   15761                 }
   15762                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   15763                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   15764                 if (user != 0 && newReceivers != null) {
   15765                     // If this is not the primary user, we need to check for
   15766                     // any receivers that should be filtered out.
   15767                     for (int i=0; i<newReceivers.size(); i++) {
   15768                         ResolveInfo ri = newReceivers.get(i);
   15769                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   15770                             newReceivers.remove(i);
   15771                             i--;
   15772                         }
   15773                     }
   15774                 }
   15775                 if (newReceivers != null && newReceivers.size() == 0) {
   15776                     newReceivers = null;
   15777                 }
   15778                 if (receivers == null) {
   15779                     receivers = newReceivers;
   15780                 } else if (newReceivers != null) {
   15781                     // We need to concatenate the additional receivers
   15782                     // found with what we have do far.  This would be easy,
   15783                     // but we also need to de-dup any receivers that are
   15784                     // singleUser.
   15785                     if (!scannedFirstReceivers) {
   15786                         // Collect any single user receivers we had already retrieved.
   15787                         scannedFirstReceivers = true;
   15788                         for (int i=0; i<receivers.size(); i++) {
   15789                             ResolveInfo ri = receivers.get(i);
   15790                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15791                                 ComponentName cn = new ComponentName(
   15792                                         ri.activityInfo.packageName, ri.activityInfo.name);
   15793                                 if (singleUserReceivers == null) {
   15794                                     singleUserReceivers = new HashSet<ComponentName>();
   15795                                 }
   15796                                 singleUserReceivers.add(cn);
   15797                             }
   15798                         }
   15799                     }
   15800                     // Add the new results to the existing results, tracking
   15801                     // and de-dupping single user receivers.
   15802                     for (int i=0; i<newReceivers.size(); i++) {
   15803                         ResolveInfo ri = newReceivers.get(i);
   15804                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15805                             ComponentName cn = new ComponentName(
   15806                                     ri.activityInfo.packageName, ri.activityInfo.name);
   15807                             if (singleUserReceivers == null) {
   15808                                 singleUserReceivers = new HashSet<ComponentName>();
   15809                             }
   15810                             if (!singleUserReceivers.contains(cn)) {
   15811                                 singleUserReceivers.add(cn);
   15812                                 receivers.add(ri);
   15813                             }
   15814                         } else {
   15815                             receivers.add(ri);
   15816                         }
   15817                     }
   15818                 }
   15819             }
   15820         } catch (RemoteException ex) {
   15821             // pm is in same process, this will never happen.
   15822         }
   15823         return receivers;
   15824     }
   15825 
   15826     private final int broadcastIntentLocked(ProcessRecord callerApp,
   15827             String callerPackage, Intent intent, String resolvedType,
   15828             IIntentReceiver resultTo, int resultCode, String resultData,
   15829             Bundle map, String requiredPermission, int appOp,
   15830             boolean ordered, boolean sticky, int callingPid, int callingUid,
   15831             int userId) {
   15832         intent = new Intent(intent);
   15833 
   15834         // By default broadcasts do not go to stopped apps.
   15835         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   15836 
   15837         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   15838             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   15839             + " ordered=" + ordered + " userid=" + userId);
   15840         if ((resultTo != null) && !ordered) {
   15841             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   15842         }
   15843 
   15844         userId = handleIncomingUser(callingPid, callingUid, userId,
   15845                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
   15846 
   15847         // Make sure that the user who is receiving this broadcast is running.
   15848         // If not, we will just skip it. Make an exception for shutdown broadcasts
   15849         // and upgrade steps.
   15850 
   15851         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
   15852             if ((callingUid != Process.SYSTEM_UID
   15853                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
   15854                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
   15855                 Slog.w(TAG, "Skipping broadcast of " + intent
   15856                         + ": user " + userId + " is stopped");
   15857                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
   15858             }
   15859         }
   15860 
   15861         /*
   15862          * Prevent non-system code (defined here to be non-persistent
   15863          * processes) from sending protected broadcasts.
   15864          */
   15865         int callingAppId = UserHandle.getAppId(callingUid);
   15866         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   15867             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
   15868             || callingAppId == Process.NFC_UID || callingUid == 0) {
   15869             // Always okay.
   15870         } else if (callerApp == null || !callerApp.persistent) {
   15871             try {
   15872                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   15873                         intent.getAction())) {
   15874                     String msg = "Permission Denial: not allowed to send broadcast "
   15875                             + intent.getAction() + " from pid="
   15876                             + callingPid + ", uid=" + callingUid;
   15877                     Slog.w(TAG, msg);
   15878                     throw new SecurityException(msg);
   15879                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   15880                     // Special case for compatibility: we don't want apps to send this,
   15881                     // but historically it has not been protected and apps may be using it
   15882                     // to poke their own app widget.  So, instead of making it protected,
   15883                     // just limit it to the caller.
   15884                     if (callerApp == null) {
   15885                         String msg = "Permission Denial: not allowed to send broadcast "
   15886                                 + intent.getAction() + " from unknown caller.";
   15887                         Slog.w(TAG, msg);
   15888                         throw new SecurityException(msg);
   15889                     } else if (intent.getComponent() != null) {
   15890                         // They are good enough to send to an explicit component...  verify
   15891                         // it is being sent to the calling app.
   15892                         if (!intent.getComponent().getPackageName().equals(
   15893                                 callerApp.info.packageName)) {
   15894                             String msg = "Permission Denial: not allowed to send broadcast "
   15895                                     + intent.getAction() + " to "
   15896                                     + intent.getComponent().getPackageName() + " from "
   15897                                     + callerApp.info.packageName;
   15898                             Slog.w(TAG, msg);
   15899                             throw new SecurityException(msg);
   15900                         }
   15901                     } else {
   15902                         // Limit broadcast to their own package.
   15903                         intent.setPackage(callerApp.info.packageName);
   15904                     }
   15905                 }
   15906             } catch (RemoteException e) {
   15907                 Slog.w(TAG, "Remote exception", e);
   15908                 return ActivityManager.BROADCAST_SUCCESS;
   15909             }
   15910         }
   15911 
   15912         final String action = intent.getAction();
   15913         if (action != null) {
   15914             switch (action) {
   15915                 case Intent.ACTION_UID_REMOVED:
   15916                 case Intent.ACTION_PACKAGE_REMOVED:
   15917                 case Intent.ACTION_PACKAGE_CHANGED:
   15918                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   15919                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   15920                     // Handle special intents: if this broadcast is from the package
   15921                     // manager about a package being removed, we need to remove all of
   15922                     // its activities from the history stack.
   15923                     if (checkComponentPermission(
   15924                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   15925                             callingPid, callingUid, -1, true)
   15926                             != PackageManager.PERMISSION_GRANTED) {
   15927                         String msg = "Permission Denial: " + intent.getAction()
   15928                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
   15929                                 + ", uid=" + callingUid + ")"
   15930                                 + " requires "
   15931                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   15932                         Slog.w(TAG, msg);
   15933                         throw new SecurityException(msg);
   15934                     }
   15935                     switch (action) {
   15936                         case Intent.ACTION_UID_REMOVED:
   15937                             final Bundle intentExtras = intent.getExtras();
   15938                             final int uid = intentExtras != null
   15939                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   15940                             if (uid >= 0) {
   15941                                 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   15942                                 synchronized (bs) {
   15943                                     bs.removeUidStatsLocked(uid);
   15944                                 }
   15945                                 mAppOpsService.uidRemoved(uid);
   15946                             }
   15947                             break;
   15948                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
   15949                             // If resources are unavailable just force stop all those packages
   15950                             // and flush the attribute cache as well.
   15951                             String list[] =
   15952                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   15953                             if (list != null && list.length > 0) {
   15954                                 for (int i = 0; i < list.length; i++) {
   15955                                     forceStopPackageLocked(list[i], -1, false, true, true,
   15956                                             false, false, userId, "storage unmount");
   15957                                 }
   15958                                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15959                                 sendPackageBroadcastLocked(
   15960                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
   15961                                         userId);
   15962                             }
   15963                             break;
   15964                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
   15965                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15966                             break;
   15967                         case Intent.ACTION_PACKAGE_REMOVED:
   15968                         case Intent.ACTION_PACKAGE_CHANGED:
   15969                             Uri data = intent.getData();
   15970                             String ssp;
   15971                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   15972                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
   15973                                 boolean fullUninstall = removed &&
   15974                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   15975                                 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   15976                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
   15977                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
   15978                                             false, true, true, false, fullUninstall, userId,
   15979                                             removed ? "pkg removed" : "pkg changed");
   15980                                 }
   15981                                 if (removed) {
   15982                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   15983                                             new String[] {ssp}, userId);
   15984                                     if (fullUninstall) {
   15985                                         mAppOpsService.packageRemoved(
   15986                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   15987 
   15988                                         // Remove all permissions granted from/to this package
   15989                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
   15990 
   15991                                         removeTasksByPackageNameLocked(ssp, userId);
   15992                                         if (userId == UserHandle.USER_OWNER) {
   15993                                             mTaskPersister.removeFromPackageCache(ssp);
   15994                                         }
   15995                                     }
   15996                                 } else {
   15997                                     removeTasksByRemovedPackageComponentsLocked(ssp, userId);
   15998                                     if (userId == UserHandle.USER_OWNER) {
   15999                                         mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
   16000                                     }
   16001                                 }
   16002                             }
   16003                             break;
   16004                     }
   16005                     break;
   16006                 case Intent.ACTION_PACKAGE_ADDED:
   16007                     // Special case for adding a package: by default turn on compatibility mode.
   16008                     Uri data = intent.getData();
   16009                     String ssp;
   16010                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
   16011                         final boolean replacing =
   16012                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   16013                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
   16014 
   16015                         if (replacing) {
   16016                             removeTasksByRemovedPackageComponentsLocked(ssp, userId);
   16017                         }
   16018                         if (userId == UserHandle.USER_OWNER) {
   16019                             mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
   16020                         }
   16021                     }
   16022                     break;
   16023                 case Intent.ACTION_TIMEZONE_CHANGED:
   16024                     // If this is the time zone changed action, queue up a message that will reset
   16025                     // the timezone of all currently running processes. This message will get
   16026                     // queued up before the broadcast happens.
   16027                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   16028                     break;
   16029                 case Intent.ACTION_TIME_CHANGED:
   16030                     // If the user set the time, let all running processes know.
   16031                     final int is24Hour =
   16032                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
   16033                                     : 0;
   16034                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   16035                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   16036                     synchronized (stats) {
   16037                         stats.noteCurrentTimeChangedLocked();
   16038                     }
   16039                     break;
   16040                 case Intent.ACTION_CLEAR_DNS_CACHE:
   16041                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   16042                     break;
   16043                 case Proxy.PROXY_CHANGE_ACTION:
   16044                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   16045                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   16046                     break;
   16047             }
   16048         }
   16049 
   16050         // Add to the sticky list if requested.
   16051         if (sticky) {
   16052             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   16053                     callingPid, callingUid)
   16054                     != PackageManager.PERMISSION_GRANTED) {
   16055                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   16056                         + callingPid + ", uid=" + callingUid
   16057                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   16058                 Slog.w(TAG, msg);
   16059                 throw new SecurityException(msg);
   16060             }
   16061             if (requiredPermission != null) {
   16062                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   16063                         + " and enforce permission " + requiredPermission);
   16064                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   16065             }
   16066             if (intent.getComponent() != null) {
   16067                 throw new SecurityException(
   16068                         "Sticky broadcasts can't target a specific component");
   16069             }
   16070             // We use userId directly here, since the "all" target is maintained
   16071             // as a separate set of sticky broadcasts.
   16072             if (userId != UserHandle.USER_ALL) {
   16073                 // But first, if this is not a broadcast to all users, then
   16074                 // make sure it doesn't conflict with an existing broadcast to
   16075                 // all users.
   16076                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   16077                         UserHandle.USER_ALL);
   16078                 if (stickies != null) {
   16079                     ArrayList<Intent> list = stickies.get(intent.getAction());
   16080                     if (list != null) {
   16081                         int N = list.size();
   16082                         int i;
   16083                         for (i=0; i<N; i++) {
   16084                             if (intent.filterEquals(list.get(i))) {
   16085                                 throw new IllegalArgumentException(
   16086                                         "Sticky broadcast " + intent + " for user "
   16087                                         + userId + " conflicts with existing global broadcast");
   16088                             }
   16089                         }
   16090                     }
   16091                 }
   16092             }
   16093             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   16094             if (stickies == null) {
   16095                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   16096                 mStickyBroadcasts.put(userId, stickies);
   16097             }
   16098             ArrayList<Intent> list = stickies.get(intent.getAction());
   16099             if (list == null) {
   16100                 list = new ArrayList<Intent>();
   16101                 stickies.put(intent.getAction(), list);
   16102             }
   16103             int N = list.size();
   16104             int i;
   16105             for (i=0; i<N; i++) {
   16106                 if (intent.filterEquals(list.get(i))) {
   16107                     // This sticky already exists, replace it.
   16108                     list.set(i, new Intent(intent));
   16109                     break;
   16110                 }
   16111             }
   16112             if (i >= N) {
   16113                 list.add(new Intent(intent));
   16114             }
   16115         }
   16116 
   16117         int[] users;
   16118         if (userId == UserHandle.USER_ALL) {
   16119             // Caller wants broadcast to go to all started users.
   16120             users = mStartedUserArray;
   16121         } else {
   16122             // Caller wants broadcast to go to one specific user.
   16123             users = new int[] {userId};
   16124         }
   16125 
   16126         // Figure out who all will receive this broadcast.
   16127         List receivers = null;
   16128         List<BroadcastFilter> registeredReceivers = null;
   16129         // Need to resolve the intent to interested receivers...
   16130         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   16131                  == 0) {
   16132             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   16133         }
   16134         if (intent.getComponent() == null) {
   16135             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   16136                 // Query one target user at a time, excluding shell-restricted users
   16137                 UserManagerService ums = getUserManagerLocked();
   16138                 for (int i = 0; i < users.length; i++) {
   16139                     if (ums.hasUserRestriction(
   16140                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   16141                         continue;
   16142                     }
   16143                     List<BroadcastFilter> registeredReceiversForUser =
   16144                             mReceiverResolver.queryIntent(intent,
   16145                                     resolvedType, false, users[i]);
   16146                     if (registeredReceivers == null) {
   16147                         registeredReceivers = registeredReceiversForUser;
   16148                     } else if (registeredReceiversForUser != null) {
   16149                         registeredReceivers.addAll(registeredReceiversForUser);
   16150                     }
   16151                 }
   16152             } else {
   16153                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   16154                         resolvedType, false, userId);
   16155             }
   16156         }
   16157 
   16158         final boolean replacePending =
   16159                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   16160 
   16161         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   16162                 + " replacePending=" + replacePending);
   16163 
   16164         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   16165         if (!ordered && NR > 0) {
   16166             // If we are not serializing this broadcast, then send the
   16167             // registered receivers separately so they don't wait for the
   16168             // components to be launched.
   16169             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   16170             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   16171                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   16172                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   16173                     ordered, sticky, false, userId);
   16174             if (DEBUG_BROADCAST) Slog.v(
   16175                     TAG, "Enqueueing parallel broadcast " + r);
   16176             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   16177             if (!replaced) {
   16178                 queue.enqueueParallelBroadcastLocked(r);
   16179                 queue.scheduleBroadcastsLocked();
   16180             }
   16181             registeredReceivers = null;
   16182             NR = 0;
   16183         }
   16184 
   16185         // Merge into one list.
   16186         int ir = 0;
   16187         if (receivers != null) {
   16188             // A special case for PACKAGE_ADDED: do not allow the package
   16189             // being added to see this broadcast.  This prevents them from
   16190             // using this as a back door to get run as soon as they are
   16191             // installed.  Maybe in the future we want to have a special install
   16192             // broadcast or such for apps, but we'd like to deliberately make
   16193             // this decision.
   16194             String skipPackages[] = null;
   16195             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   16196                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   16197                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   16198                 Uri data = intent.getData();
   16199                 if (data != null) {
   16200                     String pkgName = data.getSchemeSpecificPart();
   16201                     if (pkgName != null) {
   16202                         skipPackages = new String[] { pkgName };
   16203                     }
   16204                 }
   16205             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   16206                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   16207             }
   16208             if (skipPackages != null && (skipPackages.length > 0)) {
   16209                 for (String skipPackage : skipPackages) {
   16210                     if (skipPackage != null) {
   16211                         int NT = receivers.size();
   16212                         for (int it=0; it<NT; it++) {
   16213                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   16214                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   16215                                 receivers.remove(it);
   16216                                 it--;
   16217                                 NT--;
   16218                             }
   16219                         }
   16220                     }
   16221                 }
   16222             }
   16223 
   16224             int NT = receivers != null ? receivers.size() : 0;
   16225             int it = 0;
   16226             ResolveInfo curt = null;
   16227             BroadcastFilter curr = null;
   16228             while (it < NT && ir < NR) {
   16229                 if (curt == null) {
   16230                     curt = (ResolveInfo)receivers.get(it);
   16231                 }
   16232                 if (curr == null) {
   16233                     curr = registeredReceivers.get(ir);
   16234                 }
   16235                 if (curr.getPriority() >= curt.priority) {
   16236                     // Insert this broadcast record into the final list.
   16237                     receivers.add(it, curr);
   16238                     ir++;
   16239                     curr = null;
   16240                     it++;
   16241                     NT++;
   16242                 } else {
   16243                     // Skip to the next ResolveInfo in the final list.
   16244                     it++;
   16245                     curt = null;
   16246                 }
   16247             }
   16248         }
   16249         while (ir < NR) {
   16250             if (receivers == null) {
   16251                 receivers = new ArrayList();
   16252             }
   16253             receivers.add(registeredReceivers.get(ir));
   16254             ir++;
   16255         }
   16256 
   16257         if ((receivers != null && receivers.size() > 0)
   16258                 || resultTo != null) {
   16259             BroadcastQueue queue = broadcastQueueForIntent(intent);
   16260             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   16261                     callerPackage, callingPid, callingUid, resolvedType,
   16262                     requiredPermission, appOp, receivers, resultTo, resultCode,
   16263                     resultData, map, ordered, sticky, false, userId);
   16264             if (DEBUG_BROADCAST) Slog.v(
   16265                     TAG, "Enqueueing ordered broadcast " + r
   16266                     + ": prev had " + queue.mOrderedBroadcasts.size());
   16267             if (DEBUG_BROADCAST) {
   16268                 int seq = r.intent.getIntExtra("seq", -1);
   16269                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   16270             }
   16271             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   16272             if (!replaced) {
   16273                 queue.enqueueOrderedBroadcastLocked(r);
   16274                 queue.scheduleBroadcastsLocked();
   16275             }
   16276         }
   16277 
   16278         return ActivityManager.BROADCAST_SUCCESS;
   16279     }
   16280 
   16281     final Intent verifyBroadcastLocked(Intent intent) {
   16282         // Refuse possible leaked file descriptors
   16283         if (intent != null && intent.hasFileDescriptors() == true) {
   16284             throw new IllegalArgumentException("File descriptors passed in Intent");
   16285         }
   16286 
   16287         int flags = intent.getFlags();
   16288 
   16289         if (!mProcessesReady) {
   16290             // if the caller really truly claims to know what they're doing, go
   16291             // ahead and allow the broadcast without launching any receivers
   16292             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   16293                 intent = new Intent(intent);
   16294                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16295             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   16296                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   16297                         + " before boot completion");
   16298                 throw new IllegalStateException("Cannot broadcast before boot completed");
   16299             }
   16300         }
   16301 
   16302         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   16303             throw new IllegalArgumentException(
   16304                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   16305         }
   16306 
   16307         return intent;
   16308     }
   16309 
   16310     public final int broadcastIntent(IApplicationThread caller,
   16311             Intent intent, String resolvedType, IIntentReceiver resultTo,
   16312             int resultCode, String resultData, Bundle map,
   16313             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   16314         enforceNotIsolatedCaller("broadcastIntent");
   16315         synchronized(this) {
   16316             intent = verifyBroadcastLocked(intent);
   16317 
   16318             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   16319             final int callingPid = Binder.getCallingPid();
   16320             final int callingUid = Binder.getCallingUid();
   16321             final long origId = Binder.clearCallingIdentity();
   16322             int res = broadcastIntentLocked(callerApp,
   16323                     callerApp != null ? callerApp.info.packageName : null,
   16324                     intent, resolvedType, resultTo,
   16325                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   16326                     callingPid, callingUid, userId);
   16327             Binder.restoreCallingIdentity(origId);
   16328             return res;
   16329         }
   16330     }
   16331 
   16332     int broadcastIntentInPackage(String packageName, int uid,
   16333             Intent intent, String resolvedType, IIntentReceiver resultTo,
   16334             int resultCode, String resultData, Bundle map,
   16335             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   16336         synchronized(this) {
   16337             intent = verifyBroadcastLocked(intent);
   16338 
   16339             final long origId = Binder.clearCallingIdentity();
   16340             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   16341                     resultTo, resultCode, resultData, map, requiredPermission,
   16342                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   16343             Binder.restoreCallingIdentity(origId);
   16344             return res;
   16345         }
   16346     }
   16347 
   16348     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   16349         // Refuse possible leaked file descriptors
   16350         if (intent != null && intent.hasFileDescriptors() == true) {
   16351             throw new IllegalArgumentException("File descriptors passed in Intent");
   16352         }
   16353 
   16354         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   16355                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   16356 
   16357         synchronized(this) {
   16358             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   16359                     != PackageManager.PERMISSION_GRANTED) {
   16360                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   16361                         + Binder.getCallingPid()
   16362                         + ", uid=" + Binder.getCallingUid()
   16363                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   16364                 Slog.w(TAG, msg);
   16365                 throw new SecurityException(msg);
   16366             }
   16367             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   16368             if (stickies != null) {
   16369                 ArrayList<Intent> list = stickies.get(intent.getAction());
   16370                 if (list != null) {
   16371                     int N = list.size();
   16372                     int i;
   16373                     for (i=0; i<N; i++) {
   16374                         if (intent.filterEquals(list.get(i))) {
   16375                             list.remove(i);
   16376                             break;
   16377                         }
   16378                     }
   16379                     if (list.size() <= 0) {
   16380                         stickies.remove(intent.getAction());
   16381                     }
   16382                 }
   16383                 if (stickies.size() <= 0) {
   16384                     mStickyBroadcasts.remove(userId);
   16385                 }
   16386             }
   16387         }
   16388     }
   16389 
   16390     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   16391             String resultData, Bundle resultExtras, boolean resultAbort) {
   16392         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   16393         if (r == null) {
   16394             Slog.w(TAG, "finishReceiver called but not found on queue");
   16395             return false;
   16396         }
   16397 
   16398         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   16399     }
   16400 
   16401     void backgroundServicesFinishedLocked(int userId) {
   16402         for (BroadcastQueue queue : mBroadcastQueues) {
   16403             queue.backgroundServicesFinishedLocked(userId);
   16404         }
   16405     }
   16406 
   16407     public void finishReceiver(IBinder who, int resultCode, String resultData,
   16408             Bundle resultExtras, boolean resultAbort) {
   16409         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   16410 
   16411         // Refuse possible leaked file descriptors
   16412         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   16413             throw new IllegalArgumentException("File descriptors passed in Bundle");
   16414         }
   16415 
   16416         final long origId = Binder.clearCallingIdentity();
   16417         try {
   16418             boolean doNext = false;
   16419             BroadcastRecord r;
   16420 
   16421             synchronized(this) {
   16422                 r = broadcastRecordForReceiverLocked(who);
   16423                 if (r != null) {
   16424                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   16425                         resultData, resultExtras, resultAbort, true);
   16426                 }
   16427             }
   16428 
   16429             if (doNext) {
   16430                 r.queue.processNextBroadcast(false);
   16431             }
   16432             trimApplications();
   16433         } finally {
   16434             Binder.restoreCallingIdentity(origId);
   16435         }
   16436     }
   16437 
   16438     // =========================================================
   16439     // INSTRUMENTATION
   16440     // =========================================================
   16441 
   16442     public boolean startInstrumentation(ComponentName className,
   16443             String profileFile, int flags, Bundle arguments,
   16444             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   16445             int userId, String abiOverride) {
   16446         enforceNotIsolatedCaller("startInstrumentation");
   16447         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   16448                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   16449         // Refuse possible leaked file descriptors
   16450         if (arguments != null && arguments.hasFileDescriptors()) {
   16451             throw new IllegalArgumentException("File descriptors passed in Bundle");
   16452         }
   16453 
   16454         synchronized(this) {
   16455             InstrumentationInfo ii = null;
   16456             ApplicationInfo ai = null;
   16457             try {
   16458                 ii = mContext.getPackageManager().getInstrumentationInfo(
   16459                     className, STOCK_PM_FLAGS);
   16460                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   16461                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   16462             } catch (PackageManager.NameNotFoundException e) {
   16463             } catch (RemoteException e) {
   16464             }
   16465             if (ii == null) {
   16466                 reportStartInstrumentationFailure(watcher, className,
   16467                         "Unable to find instrumentation info for: " + className);
   16468                 return false;
   16469             }
   16470             if (ai == null) {
   16471                 reportStartInstrumentationFailure(watcher, className,
   16472                         "Unable to find instrumentation target package: " + ii.targetPackage);
   16473                 return false;
   16474             }
   16475 
   16476             int match = mContext.getPackageManager().checkSignatures(
   16477                     ii.targetPackage, ii.packageName);
   16478             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   16479                 String msg = "Permission Denial: starting instrumentation "
   16480                         + className + " from pid="
   16481                         + Binder.getCallingPid()
   16482                         + ", uid=" + Binder.getCallingPid()
   16483                         + " not allowed because package " + ii.packageName
   16484                         + " does not have a signature matching the target "
   16485                         + ii.targetPackage;
   16486                 reportStartInstrumentationFailure(watcher, className, msg);
   16487                 throw new SecurityException(msg);
   16488             }
   16489 
   16490             final long origId = Binder.clearCallingIdentity();
   16491             // Instrumentation can kill and relaunch even persistent processes
   16492             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   16493                     "start instr");
   16494             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   16495             app.instrumentationClass = className;
   16496             app.instrumentationInfo = ai;
   16497             app.instrumentationProfileFile = profileFile;
   16498             app.instrumentationArguments = arguments;
   16499             app.instrumentationWatcher = watcher;
   16500             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   16501             app.instrumentationResultClass = className;
   16502             Binder.restoreCallingIdentity(origId);
   16503         }
   16504 
   16505         return true;
   16506     }
   16507 
   16508     /**
   16509      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   16510      * error to the logs, but if somebody is watching, send the report there too.  This enables
   16511      * the "am" command to report errors with more information.
   16512      *
   16513      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   16514      * @param cn The component name of the instrumentation.
   16515      * @param report The error report.
   16516      */
   16517     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   16518             ComponentName cn, String report) {
   16519         Slog.w(TAG, report);
   16520         try {
   16521             if (watcher != null) {
   16522                 Bundle results = new Bundle();
   16523                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   16524                 results.putString("Error", report);
   16525                 watcher.instrumentationStatus(cn, -1, results);
   16526             }
   16527         } catch (RemoteException e) {
   16528             Slog.w(TAG, e);
   16529         }
   16530     }
   16531 
   16532     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   16533         if (app.instrumentationWatcher != null) {
   16534             try {
   16535                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   16536                 app.instrumentationWatcher.instrumentationFinished(
   16537                     app.instrumentationClass,
   16538                     resultCode,
   16539                     results);
   16540             } catch (RemoteException e) {
   16541             }
   16542         }
   16543         if (app.instrumentationUiAutomationConnection != null) {
   16544             try {
   16545                 app.instrumentationUiAutomationConnection.shutdown();
   16546             } catch (RemoteException re) {
   16547                 /* ignore */
   16548             }
   16549             // Only a UiAutomation can set this flag and now that
   16550             // it is finished we make sure it is reset to its default.
   16551             mUserIsMonkey = false;
   16552         }
   16553         app.instrumentationWatcher = null;
   16554         app.instrumentationUiAutomationConnection = null;
   16555         app.instrumentationClass = null;
   16556         app.instrumentationInfo = null;
   16557         app.instrumentationProfileFile = null;
   16558         app.instrumentationArguments = null;
   16559 
   16560         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   16561                 "finished inst");
   16562     }
   16563 
   16564     public void finishInstrumentation(IApplicationThread target,
   16565             int resultCode, Bundle results) {
   16566         int userId = UserHandle.getCallingUserId();
   16567         // Refuse possible leaked file descriptors
   16568         if (results != null && results.hasFileDescriptors()) {
   16569             throw new IllegalArgumentException("File descriptors passed in Intent");
   16570         }
   16571 
   16572         synchronized(this) {
   16573             ProcessRecord app = getRecordForAppLocked(target);
   16574             if (app == null) {
   16575                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   16576                 return;
   16577             }
   16578             final long origId = Binder.clearCallingIdentity();
   16579             finishInstrumentationLocked(app, resultCode, results);
   16580             Binder.restoreCallingIdentity(origId);
   16581         }
   16582     }
   16583 
   16584     // =========================================================
   16585     // CONFIGURATION
   16586     // =========================================================
   16587 
   16588     public ConfigurationInfo getDeviceConfigurationInfo() {
   16589         ConfigurationInfo config = new ConfigurationInfo();
   16590         synchronized (this) {
   16591             config.reqTouchScreen = mConfiguration.touchscreen;
   16592             config.reqKeyboardType = mConfiguration.keyboard;
   16593             config.reqNavigation = mConfiguration.navigation;
   16594             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   16595                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   16596                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   16597             }
   16598             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   16599                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   16600                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   16601             }
   16602             config.reqGlEsVersion = GL_ES_VERSION;
   16603         }
   16604         return config;
   16605     }
   16606 
   16607     ActivityStack getFocusedStack() {
   16608         return mStackSupervisor.getFocusedStack();
   16609     }
   16610 
   16611     public Configuration getConfiguration() {
   16612         Configuration ci;
   16613         synchronized(this) {
   16614             ci = new Configuration(mConfiguration);
   16615             ci.userSetLocale = false;
   16616         }
   16617         return ci;
   16618     }
   16619 
   16620     public void updatePersistentConfiguration(Configuration values) {
   16621         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16622                 "updateConfiguration()");
   16623         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   16624                 "updateConfiguration()");
   16625         if (values == null) {
   16626             throw new NullPointerException("Configuration must not be null");
   16627         }
   16628 
   16629         synchronized(this) {
   16630             final long origId = Binder.clearCallingIdentity();
   16631             updateConfigurationLocked(values, null, true, false);
   16632             Binder.restoreCallingIdentity(origId);
   16633         }
   16634     }
   16635 
   16636     public void updateConfiguration(Configuration values) {
   16637         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16638                 "updateConfiguration()");
   16639 
   16640         synchronized(this) {
   16641             if (values == null && mWindowManager != null) {
   16642                 // sentinel: fetch the current configuration from the window manager
   16643                 values = mWindowManager.computeNewConfiguration();
   16644             }
   16645 
   16646             if (mWindowManager != null) {
   16647                 mProcessList.applyDisplaySize(mWindowManager);
   16648             }
   16649 
   16650             final long origId = Binder.clearCallingIdentity();
   16651             if (values != null) {
   16652                 Settings.System.clearConfiguration(values);
   16653             }
   16654             updateConfigurationLocked(values, null, false, false);
   16655             Binder.restoreCallingIdentity(origId);
   16656         }
   16657     }
   16658 
   16659     /**
   16660      * Do either or both things: (1) change the current configuration, and (2)
   16661      * make sure the given activity is running with the (now) current
   16662      * configuration.  Returns true if the activity has been left running, or
   16663      * false if <var>starting</var> is being destroyed to match the new
   16664      * configuration.
   16665      * @param persistent TODO
   16666      */
   16667     boolean updateConfigurationLocked(Configuration values,
   16668             ActivityRecord starting, boolean persistent, boolean initLocale) {
   16669         int changes = 0;
   16670 
   16671         if (values != null) {
   16672             Configuration newConfig = new Configuration(mConfiguration);
   16673             changes = newConfig.updateFrom(values);
   16674             if (changes != 0) {
   16675                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   16676                     Slog.i(TAG, "Updating configuration to: " + values);
   16677                 }
   16678 
   16679                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   16680 
   16681                 if (values.locale != null && !initLocale) {
   16682                     saveLocaleLocked(values.locale,
   16683                                      !values.locale.equals(mConfiguration.locale),
   16684                                      values.userSetLocale);
   16685                 }
   16686 
   16687                 mConfigurationSeq++;
   16688                 if (mConfigurationSeq <= 0) {
   16689                     mConfigurationSeq = 1;
   16690                 }
   16691                 newConfig.seq = mConfigurationSeq;
   16692                 mConfiguration = newConfig;
   16693                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   16694                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
   16695                 //mUsageStatsService.noteStartConfig(newConfig);
   16696 
   16697                 final Configuration configCopy = new Configuration(mConfiguration);
   16698 
   16699                 // TODO: If our config changes, should we auto dismiss any currently
   16700                 // showing dialogs?
   16701                 mShowDialogs = shouldShowDialogs(newConfig);
   16702 
   16703                 AttributeCache ac = AttributeCache.instance();
   16704                 if (ac != null) {
   16705                     ac.updateConfiguration(configCopy);
   16706                 }
   16707 
   16708                 // Make sure all resources in our process are updated
   16709                 // right now, so that anyone who is going to retrieve
   16710                 // resource values after we return will be sure to get
   16711                 // the new ones.  This is especially important during
   16712                 // boot, where the first config change needs to guarantee
   16713                 // all resources have that config before following boot
   16714                 // code is executed.
   16715                 mSystemThread.applyConfigurationToResources(configCopy);
   16716 
   16717                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   16718                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   16719                     msg.obj = new Configuration(configCopy);
   16720                     mHandler.sendMessage(msg);
   16721                 }
   16722 
   16723                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   16724                     ProcessRecord app = mLruProcesses.get(i);
   16725                     try {
   16726                         if (app.thread != null) {
   16727                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   16728                                     + app.processName + " new config " + mConfiguration);
   16729                             app.thread.scheduleConfigurationChanged(configCopy);
   16730                         }
   16731                     } catch (Exception e) {
   16732                     }
   16733                 }
   16734                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   16735                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16736                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   16737                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16738                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   16739                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   16740                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   16741                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   16742                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   16743                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   16744                     broadcastIntentLocked(null, null, intent,
   16745                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16746                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16747                 }
   16748             }
   16749         }
   16750 
   16751         boolean kept = true;
   16752         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   16753         // mainStack is null during startup.
   16754         if (mainStack != null) {
   16755             if (changes != 0 && starting == null) {
   16756                 // If the configuration changed, and the caller is not already
   16757                 // in the process of starting an activity, then find the top
   16758                 // activity to check if its configuration needs to change.
   16759                 starting = mainStack.topRunningActivityLocked(null);
   16760             }
   16761 
   16762             if (starting != null) {
   16763                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   16764                 // And we need to make sure at this point that all other activities
   16765                 // are made visible with the correct configuration.
   16766                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   16767             }
   16768         }
   16769 
   16770         if (values != null && mWindowManager != null) {
   16771             mWindowManager.setNewConfiguration(mConfiguration);
   16772         }
   16773 
   16774         return kept;
   16775     }
   16776 
   16777     /**
   16778      * Decide based on the configuration whether we should shouw the ANR,
   16779      * crash, etc dialogs.  The idea is that if there is no affordnace to
   16780      * press the on-screen buttons, we shouldn't show the dialog.
   16781      *
   16782      * A thought: SystemUI might also want to get told about this, the Power
   16783      * dialog / global actions also might want different behaviors.
   16784      */
   16785     private static final boolean shouldShowDialogs(Configuration config) {
   16786         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   16787                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   16788     }
   16789 
   16790     /**
   16791      * Save the locale.  You must be inside a synchronized (this) block.
   16792      */
   16793     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   16794         if(isDiff) {
   16795             SystemProperties.set("user.language", l.getLanguage());
   16796             SystemProperties.set("user.region", l.getCountry());
   16797         }
   16798 
   16799         if(isPersist) {
   16800             SystemProperties.set("persist.sys.language", l.getLanguage());
   16801             SystemProperties.set("persist.sys.country", l.getCountry());
   16802             SystemProperties.set("persist.sys.localevar", l.getVariant());
   16803 
   16804             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
   16805         }
   16806     }
   16807 
   16808     @Override
   16809     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   16810         synchronized (this) {
   16811             ActivityRecord srec = ActivityRecord.forToken(token);
   16812             if (srec.task != null && srec.task.stack != null) {
   16813                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   16814             }
   16815         }
   16816         return false;
   16817     }
   16818 
   16819     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   16820             Intent resultData) {
   16821 
   16822         synchronized (this) {
   16823             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   16824             if (stack != null) {
   16825                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   16826             }
   16827             return false;
   16828         }
   16829     }
   16830 
   16831     public int getLaunchedFromUid(IBinder activityToken) {
   16832         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16833         if (srec == null) {
   16834             return -1;
   16835         }
   16836         return srec.launchedFromUid;
   16837     }
   16838 
   16839     public String getLaunchedFromPackage(IBinder activityToken) {
   16840         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16841         if (srec == null) {
   16842             return null;
   16843         }
   16844         return srec.launchedFromPackage;
   16845     }
   16846 
   16847     // =========================================================
   16848     // LIFETIME MANAGEMENT
   16849     // =========================================================
   16850 
   16851     // Returns which broadcast queue the app is the current [or imminent] receiver
   16852     // on, or 'null' if the app is not an active broadcast recipient.
   16853     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   16854         BroadcastRecord r = app.curReceiver;
   16855         if (r != null) {
   16856             return r.queue;
   16857         }
   16858 
   16859         // It's not the current receiver, but it might be starting up to become one
   16860         synchronized (this) {
   16861             for (BroadcastQueue queue : mBroadcastQueues) {
   16862                 r = queue.mPendingBroadcast;
   16863                 if (r != null && r.curApp == app) {
   16864                     // found it; report which queue it's in
   16865                     return queue;
   16866                 }
   16867             }
   16868         }
   16869 
   16870         return null;
   16871     }
   16872 
   16873     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   16874             ComponentName targetComponent, String targetProcess) {
   16875         if (!mTrackingAssociations) {
   16876             return null;
   16877         }
   16878         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   16879                 = mAssociations.get(targetUid);
   16880         if (components == null) {
   16881             components = new ArrayMap<>();
   16882             mAssociations.put(targetUid, components);
   16883         }
   16884         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   16885         if (sourceUids == null) {
   16886             sourceUids = new SparseArray<>();
   16887             components.put(targetComponent, sourceUids);
   16888         }
   16889         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   16890         if (sourceProcesses == null) {
   16891             sourceProcesses = new ArrayMap<>();
   16892             sourceUids.put(sourceUid, sourceProcesses);
   16893         }
   16894         Association ass = sourceProcesses.get(sourceProcess);
   16895         if (ass == null) {
   16896             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
   16897                     targetProcess);
   16898             sourceProcesses.put(sourceProcess, ass);
   16899         }
   16900         ass.mCount++;
   16901         ass.mNesting++;
   16902         if (ass.mNesting == 1) {
   16903             ass.mStartTime = SystemClock.uptimeMillis();
   16904         }
   16905         return ass;
   16906     }
   16907 
   16908     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
   16909             ComponentName targetComponent) {
   16910         if (!mTrackingAssociations) {
   16911             return;
   16912         }
   16913         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
   16914                 = mAssociations.get(targetUid);
   16915         if (components == null) {
   16916             return;
   16917         }
   16918         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
   16919         if (sourceUids == null) {
   16920             return;
   16921         }
   16922         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
   16923         if (sourceProcesses == null) {
   16924             return;
   16925         }
   16926         Association ass = sourceProcesses.get(sourceProcess);
   16927         if (ass == null || ass.mNesting <= 0) {
   16928             return;
   16929         }
   16930         ass.mNesting--;
   16931         if (ass.mNesting == 0) {
   16932             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
   16933         }
   16934     }
   16935 
   16936     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   16937             boolean doingAll, long now) {
   16938         if (mAdjSeq == app.adjSeq) {
   16939             // This adjustment has already been computed.
   16940             return app.curRawAdj;
   16941         }
   16942 
   16943         if (app.thread == null) {
   16944             app.adjSeq = mAdjSeq;
   16945             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16946             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16947             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   16948         }
   16949 
   16950         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   16951         app.adjSource = null;
   16952         app.adjTarget = null;
   16953         app.empty = false;
   16954         app.cached = false;
   16955 
   16956         final int activitiesSize = app.activities.size();
   16957 
   16958         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16959             // The max adjustment doesn't allow this app to be anything
   16960             // below foreground, so it is not worth doing work for it.
   16961             app.adjType = "fixed";
   16962             app.adjSeq = mAdjSeq;
   16963             app.curRawAdj = app.maxAdj;
   16964             app.foregroundActivities = false;
   16965             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   16966             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   16967             // System processes can do UI, and when they do we want to have
   16968             // them trim their memory after the user leaves the UI.  To
   16969             // facilitate this, here we need to determine whether or not it
   16970             // is currently showing UI.
   16971             app.systemNoUi = true;
   16972             if (app == TOP_APP) {
   16973                 app.systemNoUi = false;
   16974             } else if (activitiesSize > 0) {
   16975                 for (int j = 0; j < activitiesSize; j++) {
   16976                     final ActivityRecord r = app.activities.get(j);
   16977                     if (r.visible) {
   16978                         app.systemNoUi = false;
   16979                     }
   16980                 }
   16981             }
   16982             if (!app.systemNoUi) {
   16983                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   16984             }
   16985             return (app.curAdj=app.maxAdj);
   16986         }
   16987 
   16988         app.systemNoUi = false;
   16989 
   16990         // Determine the importance of the process, starting with most
   16991         // important to least, and assign an appropriate OOM adjustment.
   16992         int adj;
   16993         int schedGroup;
   16994         int procState;
   16995         boolean foregroundActivities = false;
   16996         BroadcastQueue queue;
   16997         if (app == TOP_APP) {
   16998             // The last app on the list is the foreground app.
   16999             adj = ProcessList.FOREGROUND_APP_ADJ;
   17000             schedGroup = Process.THREAD_GROUP_DEFAULT;
   17001             app.adjType = "top-activity";
   17002             foregroundActivities = true;
   17003             procState = ActivityManager.PROCESS_STATE_TOP;
   17004         } else if (app.instrumentationClass != null) {
   17005             // Don't want to kill running instrumentation.
   17006             adj = ProcessList.FOREGROUND_APP_ADJ;
   17007             schedGroup = Process.THREAD_GROUP_DEFAULT;
   17008             app.adjType = "instrumentation";
   17009             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17010         } else if ((queue = isReceivingBroadcast(app)) != null) {
   17011             // An app that is currently receiving a broadcast also
   17012             // counts as being in the foreground for OOM killer purposes.
   17013             // It's placed in a sched group based on the nature of the
   17014             // broadcast as reflected by which queue it's active in.
   17015             adj = ProcessList.FOREGROUND_APP_ADJ;
   17016             schedGroup = (queue == mFgBroadcastQueue)
   17017                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17018             app.adjType = "broadcast";
   17019             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   17020         } else if (app.executingServices.size() > 0) {
   17021             // An app that is currently executing a service callback also
   17022             // counts as being in the foreground.
   17023             adj = ProcessList.FOREGROUND_APP_ADJ;
   17024             schedGroup = app.execServicesFg ?
   17025                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17026             app.adjType = "exec-service";
   17027             procState = ActivityManager.PROCESS_STATE_SERVICE;
   17028             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   17029         } else {
   17030             // As far as we know the process is empty.  We may change our mind later.
   17031             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17032             // At this point we don't actually know the adjustment.  Use the cached adj
   17033             // value that the caller wants us to.
   17034             adj = cachedAdj;
   17035             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17036             app.cached = true;
   17037             app.empty = true;
   17038             app.adjType = "cch-empty";
   17039         }
   17040 
   17041         // Examine all activities if not already foreground.
   17042         if (!foregroundActivities && activitiesSize > 0) {
   17043             for (int j = 0; j < activitiesSize; j++) {
   17044                 final ActivityRecord r = app.activities.get(j);
   17045                 if (r.app != app) {
   17046                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   17047                             + app + "?!?");
   17048                     continue;
   17049                 }
   17050                 if (r.visible) {
   17051                     // App has a visible activity; only upgrade adjustment.
   17052                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   17053                         adj = ProcessList.VISIBLE_APP_ADJ;
   17054                         app.adjType = "visible";
   17055                     }
   17056                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   17057                         procState = ActivityManager.PROCESS_STATE_TOP;
   17058                     }
   17059                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17060                     app.cached = false;
   17061                     app.empty = false;
   17062                     foregroundActivities = true;
   17063                     break;
   17064                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   17065                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17066                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17067                         app.adjType = "pausing";
   17068                     }
   17069                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   17070                         procState = ActivityManager.PROCESS_STATE_TOP;
   17071                     }
   17072                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17073                     app.cached = false;
   17074                     app.empty = false;
   17075                     foregroundActivities = true;
   17076                 } else if (r.state == ActivityState.STOPPING) {
   17077                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17078                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17079                         app.adjType = "stopping";
   17080                     }
   17081                     // For the process state, we will at this point consider the
   17082                     // process to be cached.  It will be cached either as an activity
   17083                     // or empty depending on whether the activity is finishing.  We do
   17084                     // this so that we can treat the process as cached for purposes of
   17085                     // memory trimming (determing current memory level, trim command to
   17086                     // send to process) since there can be an arbitrary number of stopping
   17087                     // processes and they should soon all go into the cached state.
   17088                     if (!r.finishing) {
   17089                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   17090                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   17091                         }
   17092                     }
   17093                     app.cached = false;
   17094                     app.empty = false;
   17095                     foregroundActivities = true;
   17096                 } else {
   17097                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17098                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   17099                         app.adjType = "cch-act";
   17100                     }
   17101                 }
   17102             }
   17103         }
   17104 
   17105         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17106             if (app.foregroundServices) {
   17107                 // The user is aware of this app, so make it visible.
   17108                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17109                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17110                 app.cached = false;
   17111                 app.adjType = "fg-service";
   17112                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17113             } else if (app.forcingToForeground != null) {
   17114                 // The user is aware of this app, so make it visible.
   17115                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17116                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17117                 app.cached = false;
   17118                 app.adjType = "force-fg";
   17119                 app.adjSource = app.forcingToForeground;
   17120                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17121             }
   17122         }
   17123 
   17124         if (app == mHeavyWeightProcess) {
   17125             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   17126                 // We don't want to kill the current heavy-weight process.
   17127                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   17128                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17129                 app.cached = false;
   17130                 app.adjType = "heavy";
   17131             }
   17132             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   17133                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   17134             }
   17135         }
   17136 
   17137         if (app == mHomeProcess) {
   17138             if (adj > ProcessList.HOME_APP_ADJ) {
   17139                 // This process is hosting what we currently consider to be the
   17140                 // home app, so we don't want to let it go into the background.
   17141                 adj = ProcessList.HOME_APP_ADJ;
   17142                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17143                 app.cached = false;
   17144                 app.adjType = "home";
   17145             }
   17146             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   17147                 procState = ActivityManager.PROCESS_STATE_HOME;
   17148             }
   17149         }
   17150 
   17151         if (app == mPreviousProcess && app.activities.size() > 0) {
   17152             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   17153                 // This was the previous process that showed UI to the user.
   17154                 // We want to try to keep it around more aggressively, to give
   17155                 // a good experience around switching between two apps.
   17156                 adj = ProcessList.PREVIOUS_APP_ADJ;
   17157                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   17158                 app.cached = false;
   17159                 app.adjType = "previous";
   17160             }
   17161             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   17162                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   17163             }
   17164         }
   17165 
   17166         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   17167                 + " reason=" + app.adjType);
   17168 
   17169         // By default, we use the computed adjustment.  It may be changed if
   17170         // there are applications dependent on our services or providers, but
   17171         // this gives us a baseline and makes sure we don't get into an
   17172         // infinite recursion.
   17173         app.adjSeq = mAdjSeq;
   17174         app.curRawAdj = adj;
   17175         app.hasStartedServices = false;
   17176 
   17177         if (mBackupTarget != null && app == mBackupTarget.app) {
   17178             // If possible we want to avoid killing apps while they're being backed up
   17179             if (adj > ProcessList.BACKUP_APP_ADJ) {
   17180                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   17181                 adj = ProcessList.BACKUP_APP_ADJ;
   17182                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   17183                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   17184                 }
   17185                 app.adjType = "backup";
   17186                 app.cached = false;
   17187             }
   17188             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   17189                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   17190             }
   17191         }
   17192 
   17193         boolean mayBeTop = false;
   17194 
   17195         for (int is = app.services.size()-1;
   17196                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17197                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17198                         || procState > ActivityManager.PROCESS_STATE_TOP);
   17199                 is--) {
   17200             ServiceRecord s = app.services.valueAt(is);
   17201             if (s.startRequested) {
   17202                 app.hasStartedServices = true;
   17203                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   17204                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   17205                 }
   17206                 if (app.hasShownUi && app != mHomeProcess) {
   17207                     // If this process has shown some UI, let it immediately
   17208                     // go to the LRU list because it may be pretty heavy with
   17209                     // UI stuff.  We'll tag it with a label just to help
   17210                     // debug and understand what is going on.
   17211                     if (adj > ProcessList.SERVICE_ADJ) {
   17212                         app.adjType = "cch-started-ui-services";
   17213                     }
   17214                 } else {
   17215                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   17216                         // This service has seen some activity within
   17217                         // recent memory, so we will keep its process ahead
   17218                         // of the background processes.
   17219                         if (adj > ProcessList.SERVICE_ADJ) {
   17220                             adj = ProcessList.SERVICE_ADJ;
   17221                             app.adjType = "started-services";
   17222                             app.cached = false;
   17223                         }
   17224                     }
   17225                     // If we have let the service slide into the background
   17226                     // state, still have some text describing what it is doing
   17227                     // even though the service no longer has an impact.
   17228                     if (adj > ProcessList.SERVICE_ADJ) {
   17229                         app.adjType = "cch-started-services";
   17230                     }
   17231                 }
   17232             }
   17233             for (int conni = s.connections.size()-1;
   17234                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17235                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17236                             || procState > ActivityManager.PROCESS_STATE_TOP);
   17237                     conni--) {
   17238                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   17239                 for (int i = 0;
   17240                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   17241                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17242                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   17243                         i++) {
   17244                     // XXX should compute this based on the max of
   17245                     // all connected clients.
   17246                     ConnectionRecord cr = clist.get(i);
   17247                     if (cr.binding.client == app) {
   17248                         // Binding to ourself is not interesting.
   17249                         continue;
   17250                     }
   17251                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   17252                         ProcessRecord client = cr.binding.client;
   17253                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   17254                                 TOP_APP, doingAll, now);
   17255                         int clientProcState = client.curProcState;
   17256                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17257                             // If the other app is cached for any reason, for purposes here
   17258                             // we are going to consider it empty.  The specific cached state
   17259                             // doesn't propagate except under certain conditions.
   17260                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17261                         }
   17262                         String adjType = null;
   17263                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   17264                             // Not doing bind OOM management, so treat
   17265                             // this guy more like a started service.
   17266                             if (app.hasShownUi && app != mHomeProcess) {
   17267                                 // If this process has shown some UI, let it immediately
   17268                                 // go to the LRU list because it may be pretty heavy with
   17269                                 // UI stuff.  We'll tag it with a label just to help
   17270                                 // debug and understand what is going on.
   17271                                 if (adj > clientAdj) {
   17272                                     adjType = "cch-bound-ui-services";
   17273                                 }
   17274                                 app.cached = false;
   17275                                 clientAdj = adj;
   17276                                 clientProcState = procState;
   17277                             } else {
   17278                                 if (now >= (s.lastActivity
   17279                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   17280                                     // This service has not seen activity within
   17281                                     // recent memory, so allow it to drop to the
   17282                                     // LRU list if there is no other reason to keep
   17283                                     // it around.  We'll also tag it with a label just
   17284                                     // to help debug and undertand what is going on.
   17285                                     if (adj > clientAdj) {
   17286                                         adjType = "cch-bound-services";
   17287                                     }
   17288                                     clientAdj = adj;
   17289                                 }
   17290                             }
   17291                         }
   17292                         if (adj > clientAdj) {
   17293                             // If this process has recently shown UI, and
   17294                             // the process that is binding to it is less
   17295                             // important than being visible, then we don't
   17296                             // care about the binding as much as we care
   17297                             // about letting this process get into the LRU
   17298                             // list to be killed and restarted if needed for
   17299                             // memory.
   17300                             if (app.hasShownUi && app != mHomeProcess
   17301                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17302                                 adjType = "cch-bound-ui-services";
   17303                             } else {
   17304                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   17305                                         |Context.BIND_IMPORTANT)) != 0) {
   17306                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   17307                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   17308                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   17309                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   17310                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17311                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   17312                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   17313                                     adj = clientAdj;
   17314                                 } else {
   17315                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   17316                                         adj = ProcessList.VISIBLE_APP_ADJ;
   17317                                     }
   17318                                 }
   17319                                 if (!client.cached) {
   17320                                     app.cached = false;
   17321                                 }
   17322                                 adjType = "service";
   17323                             }
   17324                         }
   17325                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   17326                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   17327                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17328                             }
   17329                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   17330                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   17331                                     // Special handling of clients who are in the top state.
   17332                                     // We *may* want to consider this process to be in the
   17333                                     // top state as well, but only if there is not another
   17334                                     // reason for it to be running.  Being on the top is a
   17335                                     // special state, meaning you are specifically running
   17336                                     // for the current top app.  If the process is already
   17337                                     // running in the background for some other reason, it
   17338                                     // is more important to continue considering it to be
   17339                                     // in the background state.
   17340                                     mayBeTop = true;
   17341                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17342                                 } else {
   17343                                     // Special handling for above-top states (persistent
   17344                                     // processes).  These should not bring the current process
   17345                                     // into the top state, since they are not on top.  Instead
   17346                                     // give them the best state after that.
   17347                                     clientProcState =
   17348                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17349                                 }
   17350                             }
   17351                         } else {
   17352                             if (clientProcState <
   17353                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   17354                                 clientProcState =
   17355                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   17356                             }
   17357                         }
   17358                         if (procState > clientProcState) {
   17359                             procState = clientProcState;
   17360                         }
   17361                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   17362                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   17363                             app.pendingUiClean = true;
   17364                         }
   17365                         if (adjType != null) {
   17366                             app.adjType = adjType;
   17367                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17368                                     .REASON_SERVICE_IN_USE;
   17369                             app.adjSource = cr.binding.client;
   17370                             app.adjSourceProcState = clientProcState;
   17371                             app.adjTarget = s.name;
   17372                         }
   17373                     }
   17374                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   17375                         app.treatLikeActivity = true;
   17376                     }
   17377                     final ActivityRecord a = cr.activity;
   17378                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   17379                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   17380                                 (a.visible || a.state == ActivityState.RESUMED
   17381                                  || a.state == ActivityState.PAUSING)) {
   17382                             adj = ProcessList.FOREGROUND_APP_ADJ;
   17383                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   17384                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17385                             }
   17386                             app.cached = false;
   17387                             app.adjType = "service";
   17388                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17389                                     .REASON_SERVICE_IN_USE;
   17390                             app.adjSource = a;
   17391                             app.adjSourceProcState = procState;
   17392                             app.adjTarget = s.name;
   17393                         }
   17394                     }
   17395                 }
   17396             }
   17397         }
   17398 
   17399         for (int provi = app.pubProviders.size()-1;
   17400                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17401                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17402                         || procState > ActivityManager.PROCESS_STATE_TOP);
   17403                 provi--) {
   17404             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   17405             for (int i = cpr.connections.size()-1;
   17406                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   17407                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   17408                             || procState > ActivityManager.PROCESS_STATE_TOP);
   17409                     i--) {
   17410                 ContentProviderConnection conn = cpr.connections.get(i);
   17411                 ProcessRecord client = conn.client;
   17412                 if (client == app) {
   17413                     // Being our own client is not interesting.
   17414                     continue;
   17415                 }
   17416                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   17417                 int clientProcState = client.curProcState;
   17418                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   17419                     // If the other app is cached for any reason, for purposes here
   17420                     // we are going to consider it empty.
   17421                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17422                 }
   17423                 if (adj > clientAdj) {
   17424                     if (app.hasShownUi && app != mHomeProcess
   17425                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   17426                         app.adjType = "cch-ui-provider";
   17427                     } else {
   17428                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   17429                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   17430                         app.adjType = "provider";
   17431                     }
   17432                     app.cached &= client.cached;
   17433                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   17434                             .REASON_PROVIDER_IN_USE;
   17435                     app.adjSource = client;
   17436                     app.adjSourceProcState = clientProcState;
   17437                     app.adjTarget = cpr.name;
   17438                 }
   17439                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   17440                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   17441                         // Special handling of clients who are in the top state.
   17442                         // We *may* want to consider this process to be in the
   17443                         // top state as well, but only if there is not another
   17444                         // reason for it to be running.  Being on the top is a
   17445                         // special state, meaning you are specifically running
   17446                         // for the current top app.  If the process is already
   17447                         // running in the background for some other reason, it
   17448                         // is more important to continue considering it to be
   17449                         // in the background state.
   17450                         mayBeTop = true;
   17451                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   17452                     } else {
   17453                         // Special handling for above-top states (persistent
   17454                         // processes).  These should not bring the current process
   17455                         // into the top state, since they are not on top.  Instead
   17456                         // give them the best state after that.
   17457                         clientProcState =
   17458                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17459                     }
   17460                 }
   17461                 if (procState > clientProcState) {
   17462                     procState = clientProcState;
   17463                 }
   17464                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   17465                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17466                 }
   17467             }
   17468             // If the provider has external (non-framework) process
   17469             // dependencies, ensure that its adjustment is at least
   17470             // FOREGROUND_APP_ADJ.
   17471             if (cpr.hasExternalProcessHandles()) {
   17472                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   17473                     adj = ProcessList.FOREGROUND_APP_ADJ;
   17474                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   17475                     app.cached = false;
   17476                     app.adjType = "provider";
   17477                     app.adjTarget = cpr.name;
   17478                 }
   17479                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   17480                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17481                 }
   17482             }
   17483         }
   17484 
   17485         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   17486             // A client of one of our services or providers is in the top state.  We
   17487             // *may* want to be in the top state, but not if we are already running in
   17488             // the background for some other reason.  For the decision here, we are going
   17489             // to pick out a few specific states that we want to remain in when a client
   17490             // is top (states that tend to be longer-term) and otherwise allow it to go
   17491             // to the top state.
   17492             switch (procState) {
   17493                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   17494                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   17495                 case ActivityManager.PROCESS_STATE_SERVICE:
   17496                     // These all are longer-term states, so pull them up to the top
   17497                     // of the background states, but not all the way to the top state.
   17498                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17499                     break;
   17500                 default:
   17501                     // Otherwise, top is a better choice, so take it.
   17502                     procState = ActivityManager.PROCESS_STATE_TOP;
   17503                     break;
   17504             }
   17505         }
   17506 
   17507         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   17508             if (app.hasClientActivities) {
   17509                 // This is a cached process, but with client activities.  Mark it so.
   17510                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   17511                 app.adjType = "cch-client-act";
   17512             } else if (app.treatLikeActivity) {
   17513                 // This is a cached process, but somebody wants us to treat it like it has
   17514                 // an activity, okay!
   17515                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   17516                 app.adjType = "cch-as-act";
   17517             }
   17518         }
   17519 
   17520         if (adj == ProcessList.SERVICE_ADJ) {
   17521             if (doingAll) {
   17522                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   17523                 mNewNumServiceProcs++;
   17524                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   17525                 if (!app.serviceb) {
   17526                     // This service isn't far enough down on the LRU list to
   17527                     // normally be a B service, but if we are low on RAM and it
   17528                     // is large we want to force it down since we would prefer to
   17529                     // keep launcher over it.
   17530                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   17531                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   17532                         app.serviceHighRam = true;
   17533                         app.serviceb = true;
   17534                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   17535                     } else {
   17536                         mNewNumAServiceProcs++;
   17537                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   17538                     }
   17539                 } else {
   17540                     app.serviceHighRam = false;
   17541                 }
   17542             }
   17543             if (app.serviceb) {
   17544                 adj = ProcessList.SERVICE_B_ADJ;
   17545             }
   17546         }
   17547 
   17548         app.curRawAdj = adj;
   17549 
   17550         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   17551         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   17552         if (adj > app.maxAdj) {
   17553             adj = app.maxAdj;
   17554             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   17555                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17556             }
   17557         }
   17558 
   17559         // Do final modification to adj.  Everything we do between here and applying
   17560         // the final setAdj must be done in this function, because we will also use
   17561         // it when computing the final cached adj later.  Note that we don't need to
   17562         // worry about this for max adj above, since max adj will always be used to
   17563         // keep it out of the cached vaues.
   17564         app.curAdj = app.modifyRawOomAdj(adj);
   17565         app.curSchedGroup = schedGroup;
   17566         app.curProcState = procState;
   17567         app.foregroundActivities = foregroundActivities;
   17568 
   17569         return app.curRawAdj;
   17570     }
   17571 
   17572     /**
   17573      * Record new PSS sample for a process.
   17574      */
   17575     void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
   17576         proc.lastPssTime = now;
   17577         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
   17578         if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
   17579                 + ": " + pss + " lastPss=" + proc.lastPss
   17580                 + " state=" + ProcessList.makeProcStateString(procState));
   17581         if (proc.initialIdlePss == 0) {
   17582             proc.initialIdlePss = pss;
   17583         }
   17584         proc.lastPss = pss;
   17585         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   17586             proc.lastCachedPss = pss;
   17587         }
   17588     }
   17589 
   17590     /**
   17591      * Schedule PSS collection of a process.
   17592      */
   17593     void requestPssLocked(ProcessRecord proc, int procState) {
   17594         if (mPendingPssProcesses.contains(proc)) {
   17595             return;
   17596         }
   17597         if (mPendingPssProcesses.size() == 0) {
   17598             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17599         }
   17600         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   17601         proc.pssProcState = procState;
   17602         mPendingPssProcesses.add(proc);
   17603     }
   17604 
   17605     /**
   17606      * Schedule PSS collection of all processes.
   17607      */
   17608     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   17609         if (!always) {
   17610             if (now < (mLastFullPssTime +
   17611                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   17612                 return;
   17613             }
   17614         }
   17615         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   17616         mLastFullPssTime = now;
   17617         mFullPssPending = true;
   17618         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   17619         mPendingPssProcesses.clear();
   17620         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   17621             ProcessRecord app = mLruProcesses.get(i);
   17622             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   17623                 app.pssProcState = app.setProcState;
   17624                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17625                         mTestPssMode, isSleeping(), now);
   17626                 mPendingPssProcesses.add(app);
   17627             }
   17628         }
   17629         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17630     }
   17631 
   17632     public void setTestPssMode(boolean enabled) {
   17633         synchronized (this) {
   17634             mTestPssMode = enabled;
   17635             if (enabled) {
   17636                 // Whenever we enable the mode, we want to take a snapshot all of current
   17637                 // process mem use.
   17638                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
   17639             }
   17640         }
   17641     }
   17642 
   17643     /**
   17644      * Ask a given process to GC right now.
   17645      */
   17646     final void performAppGcLocked(ProcessRecord app) {
   17647         try {
   17648             app.lastRequestedGc = SystemClock.uptimeMillis();
   17649             if (app.thread != null) {
   17650                 if (app.reportLowMemory) {
   17651                     app.reportLowMemory = false;
   17652                     app.thread.scheduleLowMemory();
   17653                 } else {
   17654                     app.thread.processInBackground();
   17655                 }
   17656             }
   17657         } catch (Exception e) {
   17658             // whatever.
   17659         }
   17660     }
   17661 
   17662     /**
   17663      * Returns true if things are idle enough to perform GCs.
   17664      */
   17665     private final boolean canGcNowLocked() {
   17666         boolean processingBroadcasts = false;
   17667         for (BroadcastQueue q : mBroadcastQueues) {
   17668             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   17669                 processingBroadcasts = true;
   17670             }
   17671         }
   17672         return !processingBroadcasts
   17673                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
   17674     }
   17675 
   17676     /**
   17677      * Perform GCs on all processes that are waiting for it, but only
   17678      * if things are idle.
   17679      */
   17680     final void performAppGcsLocked() {
   17681         final int N = mProcessesToGc.size();
   17682         if (N <= 0) {
   17683             return;
   17684         }
   17685         if (canGcNowLocked()) {
   17686             while (mProcessesToGc.size() > 0) {
   17687                 ProcessRecord proc = mProcessesToGc.remove(0);
   17688                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   17689                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   17690                             <= SystemClock.uptimeMillis()) {
   17691                         // To avoid spamming the system, we will GC processes one
   17692                         // at a time, waiting a few seconds between each.
   17693                         performAppGcLocked(proc);
   17694                         scheduleAppGcsLocked();
   17695                         return;
   17696                     } else {
   17697                         // It hasn't been long enough since we last GCed this
   17698                         // process...  put it in the list to wait for its time.
   17699                         addProcessToGcListLocked(proc);
   17700                         break;
   17701                     }
   17702                 }
   17703             }
   17704 
   17705             scheduleAppGcsLocked();
   17706         }
   17707     }
   17708 
   17709     /**
   17710      * If all looks good, perform GCs on all processes waiting for them.
   17711      */
   17712     final void performAppGcsIfAppropriateLocked() {
   17713         if (canGcNowLocked()) {
   17714             performAppGcsLocked();
   17715             return;
   17716         }
   17717         // Still not idle, wait some more.
   17718         scheduleAppGcsLocked();
   17719     }
   17720 
   17721     /**
   17722      * Schedule the execution of all pending app GCs.
   17723      */
   17724     final void scheduleAppGcsLocked() {
   17725         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   17726 
   17727         if (mProcessesToGc.size() > 0) {
   17728             // Schedule a GC for the time to the next process.
   17729             ProcessRecord proc = mProcessesToGc.get(0);
   17730             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   17731 
   17732             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   17733             long now = SystemClock.uptimeMillis();
   17734             if (when < (now+GC_TIMEOUT)) {
   17735                 when = now + GC_TIMEOUT;
   17736             }
   17737             mHandler.sendMessageAtTime(msg, when);
   17738         }
   17739     }
   17740 
   17741     /**
   17742      * Add a process to the array of processes waiting to be GCed.  Keeps the
   17743      * list in sorted order by the last GC time.  The process can't already be
   17744      * on the list.
   17745      */
   17746     final void addProcessToGcListLocked(ProcessRecord proc) {
   17747         boolean added = false;
   17748         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   17749             if (mProcessesToGc.get(i).lastRequestedGc <
   17750                     proc.lastRequestedGc) {
   17751                 added = true;
   17752                 mProcessesToGc.add(i+1, proc);
   17753                 break;
   17754             }
   17755         }
   17756         if (!added) {
   17757             mProcessesToGc.add(0, proc);
   17758         }
   17759     }
   17760 
   17761     /**
   17762      * Set up to ask a process to GC itself.  This will either do it
   17763      * immediately, or put it on the list of processes to gc the next
   17764      * time things are idle.
   17765      */
   17766     final void scheduleAppGcLocked(ProcessRecord app) {
   17767         long now = SystemClock.uptimeMillis();
   17768         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   17769             return;
   17770         }
   17771         if (!mProcessesToGc.contains(app)) {
   17772             addProcessToGcListLocked(app);
   17773             scheduleAppGcsLocked();
   17774         }
   17775     }
   17776 
   17777     final void checkExcessivePowerUsageLocked(boolean doKills) {
   17778         updateCpuStatsNow();
   17779 
   17780         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17781         boolean doWakeKills = doKills;
   17782         boolean doCpuKills = doKills;
   17783         if (mLastPowerCheckRealtime == 0) {
   17784             doWakeKills = false;
   17785         }
   17786         if (mLastPowerCheckUptime == 0) {
   17787             doCpuKills = false;
   17788         }
   17789         if (stats.isScreenOn()) {
   17790             doWakeKills = false;
   17791         }
   17792         final long curRealtime = SystemClock.elapsedRealtime();
   17793         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   17794         final long curUptime = SystemClock.uptimeMillis();
   17795         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   17796         mLastPowerCheckRealtime = curRealtime;
   17797         mLastPowerCheckUptime = curUptime;
   17798         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   17799             doWakeKills = false;
   17800         }
   17801         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   17802             doCpuKills = false;
   17803         }
   17804         int i = mLruProcesses.size();
   17805         while (i > 0) {
   17806             i--;
   17807             ProcessRecord app = mLruProcesses.get(i);
   17808             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   17809                 long wtime;
   17810                 synchronized (stats) {
   17811                     wtime = stats.getProcessWakeTime(app.info.uid,
   17812                             app.pid, curRealtime);
   17813                 }
   17814                 long wtimeUsed = wtime - app.lastWakeTime;
   17815                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   17816                 if (DEBUG_POWER) {
   17817                     StringBuilder sb = new StringBuilder(128);
   17818                     sb.append("Wake for ");
   17819                     app.toShortString(sb);
   17820                     sb.append(": over ");
   17821                     TimeUtils.formatDuration(realtimeSince, sb);
   17822                     sb.append(" used ");
   17823                     TimeUtils.formatDuration(wtimeUsed, sb);
   17824                     sb.append(" (");
   17825                     sb.append((wtimeUsed*100)/realtimeSince);
   17826                     sb.append("%)");
   17827                     Slog.i(TAG, sb.toString());
   17828                     sb.setLength(0);
   17829                     sb.append("CPU for ");
   17830                     app.toShortString(sb);
   17831                     sb.append(": over ");
   17832                     TimeUtils.formatDuration(uptimeSince, sb);
   17833                     sb.append(" used ");
   17834                     TimeUtils.formatDuration(cputimeUsed, sb);
   17835                     sb.append(" (");
   17836                     sb.append((cputimeUsed*100)/uptimeSince);
   17837                     sb.append("%)");
   17838                     Slog.i(TAG, sb.toString());
   17839                 }
   17840                 // If a process has held a wake lock for more
   17841                 // than 50% of the time during this period,
   17842                 // that sounds bad.  Kill!
   17843                 if (doWakeKills && realtimeSince > 0
   17844                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   17845                     synchronized (stats) {
   17846                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   17847                                 realtimeSince, wtimeUsed);
   17848                     }
   17849                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   17850                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   17851                 } else if (doCpuKills && uptimeSince > 0
   17852                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   17853                     synchronized (stats) {
   17854                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   17855                                 uptimeSince, cputimeUsed);
   17856                     }
   17857                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   17858                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   17859                 } else {
   17860                     app.lastWakeTime = wtime;
   17861                     app.lastCpuTime = app.curCpuTime;
   17862                 }
   17863             }
   17864         }
   17865     }
   17866 
   17867     private final boolean applyOomAdjLocked(ProcessRecord app,
   17868             ProcessRecord TOP_APP, boolean doingAll, long now) {
   17869         boolean success = true;
   17870 
   17871         if (app.curRawAdj != app.setRawAdj) {
   17872             app.setRawAdj = app.curRawAdj;
   17873         }
   17874 
   17875         int changes = 0;
   17876 
   17877         if (app.curAdj != app.setAdj) {
   17878             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   17879             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   17880                 TAG, "Set " + app.pid + " " + app.processName +
   17881                 " adj " + app.curAdj + ": " + app.adjType);
   17882             app.setAdj = app.curAdj;
   17883         }
   17884 
   17885         if (app.setSchedGroup != app.curSchedGroup) {
   17886             app.setSchedGroup = app.curSchedGroup;
   17887             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17888                     "Setting process group of " + app.processName
   17889                     + " to " + app.curSchedGroup);
   17890             if (app.waitingToKill != null &&
   17891                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   17892                 app.kill(app.waitingToKill, true);
   17893                 success = false;
   17894             } else {
   17895                 if (true) {
   17896                     long oldId = Binder.clearCallingIdentity();
   17897                     try {
   17898                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   17899                     } catch (Exception e) {
   17900                         Slog.w(TAG, "Failed setting process group of " + app.pid
   17901                                 + " to " + app.curSchedGroup);
   17902                         e.printStackTrace();
   17903                     } finally {
   17904                         Binder.restoreCallingIdentity(oldId);
   17905                     }
   17906                 } else {
   17907                     if (app.thread != null) {
   17908                         try {
   17909                             app.thread.setSchedulingGroup(app.curSchedGroup);
   17910                         } catch (RemoteException e) {
   17911                         }
   17912                     }
   17913                 }
   17914                 Process.setSwappiness(app.pid,
   17915                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   17916             }
   17917         }
   17918         if (app.repForegroundActivities != app.foregroundActivities) {
   17919             app.repForegroundActivities = app.foregroundActivities;
   17920             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   17921         }
   17922         if (app.repProcState != app.curProcState) {
   17923             app.repProcState = app.curProcState;
   17924             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   17925             if (app.thread != null) {
   17926                 try {
   17927                     if (false) {
   17928                         //RuntimeException h = new RuntimeException("here");
   17929                         Slog.i(TAG, "Sending new process state " + app.repProcState
   17930                                 + " to " + app /*, h*/);
   17931                     }
   17932                     app.thread.setProcessState(app.repProcState);
   17933                 } catch (RemoteException e) {
   17934                 }
   17935             }
   17936         }
   17937         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   17938                 app.setProcState)) {
   17939             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
   17940                 // Experimental code to more aggressively collect pss while
   17941                 // running test...  the problem is that this tends to collect
   17942                 // the data right when a process is transitioning between process
   17943                 // states, which well tend to give noisy data.
   17944                 long start = SystemClock.uptimeMillis();
   17945                 long pss = Debug.getPss(app.pid, mTmpLong, null);
   17946                 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
   17947                 mPendingPssProcesses.remove(app);
   17948                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
   17949                         + " to " + app.curProcState + ": "
   17950                         + (SystemClock.uptimeMillis()-start) + "ms");
   17951             }
   17952             app.lastStateTime = now;
   17953             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17954                     mTestPssMode, isSleeping(), now);
   17955             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   17956                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   17957                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   17958                     + (app.nextPssTime-now) + ": " + app);
   17959         } else {
   17960             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   17961                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
   17962                     mTestPssMode)))) {
   17963                 requestPssLocked(app, app.setProcState);
   17964                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   17965                         mTestPssMode, isSleeping(), now);
   17966             } else if (false && DEBUG_PSS) {
   17967                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   17968             }
   17969         }
   17970         if (app.setProcState != app.curProcState) {
   17971             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17972                     "Proc state change of " + app.processName
   17973                     + " to " + app.curProcState);
   17974             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17975             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17976             if (setImportant && !curImportant) {
   17977                 // This app is no longer something we consider important enough to allow to
   17978                 // use arbitrary amounts of battery power.  Note
   17979                 // its current wake lock time to later know to kill it if
   17980                 // it is not behaving well.
   17981                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17982                 synchronized (stats) {
   17983                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   17984                             app.pid, SystemClock.elapsedRealtime());
   17985                 }
   17986                 app.lastCpuTime = app.curCpuTime;
   17987 
   17988             }
   17989             app.setProcState = app.curProcState;
   17990             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   17991                 app.notCachedSinceIdle = false;
   17992             }
   17993             if (!doingAll) {
   17994                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   17995             } else {
   17996                 app.procStateChanged = true;
   17997             }
   17998         }
   17999 
   18000         if (changes != 0) {
   18001             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   18002             int i = mPendingProcessChanges.size()-1;
   18003             ProcessChangeItem item = null;
   18004             while (i >= 0) {
   18005                 item = mPendingProcessChanges.get(i);
   18006                 if (item.pid == app.pid) {
   18007                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   18008                     break;
   18009                 }
   18010                 i--;
   18011             }
   18012             if (i < 0) {
   18013                 // No existing item in pending changes; need a new one.
   18014                 final int NA = mAvailProcessChanges.size();
   18015                 if (NA > 0) {
   18016                     item = mAvailProcessChanges.remove(NA-1);
   18017                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   18018                 } else {
   18019                     item = new ProcessChangeItem();
   18020                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   18021                 }
   18022                 item.changes = 0;
   18023                 item.pid = app.pid;
   18024                 item.uid = app.info.uid;
   18025                 if (mPendingProcessChanges.size() == 0) {
   18026                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   18027                             "*** Enqueueing dispatch processes changed!");
   18028                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   18029                 }
   18030                 mPendingProcessChanges.add(item);
   18031             }
   18032             item.changes |= changes;
   18033             item.processState = app.repProcState;
   18034             item.foregroundActivities = app.repForegroundActivities;
   18035             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   18036                     + Integer.toHexString(System.identityHashCode(item))
   18037                     + " " + app.toShortString() + ": changes=" + item.changes
   18038                     + " procState=" + item.processState
   18039                     + " foreground=" + item.foregroundActivities
   18040                     + " type=" + app.adjType + " source=" + app.adjSource
   18041                     + " target=" + app.adjTarget);
   18042         }
   18043 
   18044         return success;
   18045     }
   18046 
   18047     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   18048         if (proc.thread != null) {
   18049             if (proc.baseProcessTracker != null) {
   18050                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   18051             }
   18052             if (proc.repProcState >= 0) {
   18053                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
   18054                         proc.repProcState);
   18055             }
   18056         }
   18057     }
   18058 
   18059     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   18060             ProcessRecord TOP_APP, boolean doingAll, long now) {
   18061         if (app.thread == null) {
   18062             return false;
   18063         }
   18064 
   18065         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   18066 
   18067         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
   18068     }
   18069 
   18070     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   18071             boolean oomAdj) {
   18072         if (isForeground != proc.foregroundServices) {
   18073             proc.foregroundServices = isForeground;
   18074             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   18075                     proc.info.uid);
   18076             if (isForeground) {
   18077                 if (curProcs == null) {
   18078                     curProcs = new ArrayList<ProcessRecord>();
   18079                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   18080                 }
   18081                 if (!curProcs.contains(proc)) {
   18082                     curProcs.add(proc);
   18083                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   18084                             proc.info.packageName, proc.info.uid);
   18085                 }
   18086             } else {
   18087                 if (curProcs != null) {
   18088                     if (curProcs.remove(proc)) {
   18089                         mBatteryStatsService.noteEvent(
   18090                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   18091                                 proc.info.packageName, proc.info.uid);
   18092                         if (curProcs.size() <= 0) {
   18093                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   18094                         }
   18095                     }
   18096                 }
   18097             }
   18098             if (oomAdj) {
   18099                 updateOomAdjLocked();
   18100             }
   18101         }
   18102     }
   18103 
   18104     private final ActivityRecord resumedAppLocked() {
   18105         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   18106         String pkg;
   18107         int uid;
   18108         if (act != null) {
   18109             pkg = act.packageName;
   18110             uid = act.info.applicationInfo.uid;
   18111         } else {
   18112             pkg = null;
   18113             uid = -1;
   18114         }
   18115         // Has the UID or resumed package name changed?
   18116         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   18117                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   18118             if (mCurResumedPackage != null) {
   18119                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   18120                         mCurResumedPackage, mCurResumedUid);
   18121             }
   18122             mCurResumedPackage = pkg;
   18123             mCurResumedUid = uid;
   18124             if (mCurResumedPackage != null) {
   18125                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   18126                         mCurResumedPackage, mCurResumedUid);
   18127             }
   18128         }
   18129         return act;
   18130     }
   18131 
   18132     final boolean updateOomAdjLocked(ProcessRecord app) {
   18133         final ActivityRecord TOP_ACT = resumedAppLocked();
   18134         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   18135         final boolean wasCached = app.cached;
   18136 
   18137         mAdjSeq++;
   18138 
   18139         // This is the desired cached adjusment we want to tell it to use.
   18140         // If our app is currently cached, we know it, and that is it.  Otherwise,
   18141         // we don't know it yet, and it needs to now be cached we will then
   18142         // need to do a complete oom adj.
   18143         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   18144                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   18145         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   18146                 SystemClock.uptimeMillis());
   18147         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   18148             // Changed to/from cached state, so apps after it in the LRU
   18149             // list may also be changed.
   18150             updateOomAdjLocked();
   18151         }
   18152         return success;
   18153     }
   18154 
   18155     final void updateOomAdjLocked() {
   18156         final ActivityRecord TOP_ACT = resumedAppLocked();
   18157         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   18158         final long now = SystemClock.uptimeMillis();
   18159         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   18160         final int N = mLruProcesses.size();
   18161 
   18162         if (false) {
   18163             RuntimeException e = new RuntimeException();
   18164             e.fillInStackTrace();
   18165             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   18166         }
   18167 
   18168         mAdjSeq++;
   18169         mNewNumServiceProcs = 0;
   18170         mNewNumAServiceProcs = 0;
   18171 
   18172         final int emptyProcessLimit;
   18173         final int cachedProcessLimit;
   18174         if (mProcessLimit <= 0) {
   18175             emptyProcessLimit = cachedProcessLimit = 0;
   18176         } else if (mProcessLimit == 1) {
   18177             emptyProcessLimit = 1;
   18178             cachedProcessLimit = 0;
   18179         } else {
   18180             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   18181             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   18182         }
   18183 
   18184         // Let's determine how many processes we have running vs.
   18185         // how many slots we have for background processes; we may want
   18186         // to put multiple processes in a slot of there are enough of
   18187         // them.
   18188         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   18189                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   18190         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   18191         if (numEmptyProcs > cachedProcessLimit) {
   18192             // If there are more empty processes than our limit on cached
   18193             // processes, then use the cached process limit for the factor.
   18194             // This ensures that the really old empty processes get pushed
   18195             // down to the bottom, so if we are running low on memory we will
   18196             // have a better chance at keeping around more cached processes
   18197             // instead of a gazillion empty processes.
   18198             numEmptyProcs = cachedProcessLimit;
   18199         }
   18200         int emptyFactor = numEmptyProcs/numSlots;
   18201         if (emptyFactor < 1) emptyFactor = 1;
   18202         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   18203         if (cachedFactor < 1) cachedFactor = 1;
   18204         int stepCached = 0;
   18205         int stepEmpty = 0;
   18206         int numCached = 0;
   18207         int numEmpty = 0;
   18208         int numTrimming = 0;
   18209 
   18210         mNumNonCachedProcs = 0;
   18211         mNumCachedHiddenProcs = 0;
   18212 
   18213         // First update the OOM adjustment for each of the
   18214         // application processes based on their current state.
   18215         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   18216         int nextCachedAdj = curCachedAdj+1;
   18217         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   18218         int nextEmptyAdj = curEmptyAdj+2;
   18219         for (int i=N-1; i>=0; i--) {
   18220             ProcessRecord app = mLruProcesses.get(i);
   18221             if (!app.killedByAm && app.thread != null) {
   18222                 app.procStateChanged = false;
   18223                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   18224 
   18225                 // If we haven't yet assigned the final cached adj
   18226                 // to the process, do that now.
   18227                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   18228                     switch (app.curProcState) {
   18229                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   18230                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   18231                             // This process is a cached process holding activities...
   18232                             // assign it the next cached value for that type, and then
   18233                             // step that cached level.
   18234                             app.curRawAdj = curCachedAdj;
   18235                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   18236                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
   18237                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   18238                                     + ")");
   18239                             if (curCachedAdj != nextCachedAdj) {
   18240                                 stepCached++;
   18241                                 if (stepCached >= cachedFactor) {
   18242                                     stepCached = 0;
   18243                                     curCachedAdj = nextCachedAdj;
   18244                                     nextCachedAdj += 2;
   18245                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   18246                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   18247                                     }
   18248                                 }
   18249                             }
   18250                             break;
   18251                         default:
   18252                             // For everything else, assign next empty cached process
   18253                             // level and bump that up.  Note that this means that
   18254                             // long-running services that have dropped down to the
   18255                             // cached level will be treated as empty (since their process
   18256                             // state is still as a service), which is what we want.
   18257                             app.curRawAdj = curEmptyAdj;
   18258                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   18259                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
   18260                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   18261                                     + ")");
   18262                             if (curEmptyAdj != nextEmptyAdj) {
   18263                                 stepEmpty++;
   18264                                 if (stepEmpty >= emptyFactor) {
   18265                                     stepEmpty = 0;
   18266                                     curEmptyAdj = nextEmptyAdj;
   18267                                     nextEmptyAdj += 2;
   18268                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   18269                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   18270                                     }
   18271                                 }
   18272                             }
   18273                             break;
   18274                     }
   18275                 }
   18276 
   18277                 applyOomAdjLocked(app, TOP_APP, true, now);
   18278 
   18279                 // Count the number of process types.
   18280                 switch (app.curProcState) {
   18281                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   18282                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   18283                         mNumCachedHiddenProcs++;
   18284                         numCached++;
   18285                         if (numCached > cachedProcessLimit) {
   18286                             app.kill("cached #" + numCached, true);
   18287                         }
   18288                         break;
   18289                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   18290                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   18291                                 && app.lastActivityTime < oldTime) {
   18292                             app.kill("empty for "
   18293                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   18294                                     / 1000) + "s", true);
   18295                         } else {
   18296                             numEmpty++;
   18297                             if (numEmpty > emptyProcessLimit) {
   18298                                 app.kill("empty #" + numEmpty, true);
   18299                             }
   18300                         }
   18301                         break;
   18302                     default:
   18303                         mNumNonCachedProcs++;
   18304                         break;
   18305                 }
   18306 
   18307                 if (app.isolated && app.services.size() <= 0) {
   18308                     // If this is an isolated process, and there are no
   18309                     // services running in it, then the process is no longer
   18310                     // needed.  We agressively kill these because we can by
   18311                     // definition not re-use the same process again, and it is
   18312                     // good to avoid having whatever code was running in them
   18313                     // left sitting around after no longer needed.
   18314                     app.kill("isolated not needed", true);
   18315                 }
   18316 
   18317                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   18318                         && !app.killedByAm) {
   18319                     numTrimming++;
   18320                 }
   18321             }
   18322         }
   18323 
   18324         mNumServiceProcs = mNewNumServiceProcs;
   18325 
   18326         // Now determine the memory trimming level of background processes.
   18327         // Unfortunately we need to start at the back of the list to do this
   18328         // properly.  We only do this if the number of background apps we
   18329         // are managing to keep around is less than half the maximum we desire;
   18330         // if we are keeping a good number around, we'll let them use whatever
   18331         // memory they want.
   18332         final int numCachedAndEmpty = numCached + numEmpty;
   18333         int memFactor;
   18334         if (numCached <= ProcessList.TRIM_CACHED_APPS
   18335                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   18336             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   18337                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   18338             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   18339                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   18340             } else {
   18341                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   18342             }
   18343         } else {
   18344             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   18345         }
   18346         // We always allow the memory level to go up (better).  We only allow it to go
   18347         // down if we are in a state where that is allowed, *and* the total number of processes
   18348         // has gone down since last time.
   18349         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   18350                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   18351                 + " last=" + mLastNumProcesses);
   18352         if (memFactor > mLastMemoryLevel) {
   18353             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   18354                 memFactor = mLastMemoryLevel;
   18355                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   18356             }
   18357         }
   18358         mLastMemoryLevel = memFactor;
   18359         mLastNumProcesses = mLruProcesses.size();
   18360         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
   18361         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   18362         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   18363             if (mLowRamStartTime == 0) {
   18364                 mLowRamStartTime = now;
   18365             }
   18366             int step = 0;
   18367             int fgTrimLevel;
   18368             switch (memFactor) {
   18369                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   18370                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   18371                     break;
   18372                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   18373                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   18374                     break;
   18375                 default:
   18376                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   18377                     break;
   18378             }
   18379             int factor = numTrimming/3;
   18380             int minFactor = 2;
   18381             if (mHomeProcess != null) minFactor++;
   18382             if (mPreviousProcess != null) minFactor++;
   18383             if (factor < minFactor) factor = minFactor;
   18384             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   18385             for (int i=N-1; i>=0; i--) {
   18386                 ProcessRecord app = mLruProcesses.get(i);
   18387                 if (allChanged || app.procStateChanged) {
   18388                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   18389                     app.procStateChanged = false;
   18390                 }
   18391                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   18392                         && !app.killedByAm) {
   18393                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   18394                         try {
   18395                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18396                                     "Trimming memory of " + app.processName
   18397                                     + " to " + curLevel);
   18398                             app.thread.scheduleTrimMemory(curLevel);
   18399                         } catch (RemoteException e) {
   18400                         }
   18401                         if (false) {
   18402                             // For now we won't do this; our memory trimming seems
   18403                             // to be good enough at this point that destroying
   18404                             // activities causes more harm than good.
   18405                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   18406                                     && app != mHomeProcess && app != mPreviousProcess) {
   18407                                 // Need to do this on its own message because the stack may not
   18408                                 // be in a consistent state at this point.
   18409                                 // For these apps we will also finish their activities
   18410                                 // to help them free memory.
   18411                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   18412                             }
   18413                         }
   18414                     }
   18415                     app.trimMemoryLevel = curLevel;
   18416                     step++;
   18417                     if (step >= factor) {
   18418                         step = 0;
   18419                         switch (curLevel) {
   18420                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   18421                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   18422                                 break;
   18423                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   18424                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   18425                                 break;
   18426                         }
   18427                     }
   18428                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   18429                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   18430                             && app.thread != null) {
   18431                         try {
   18432                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18433                                     "Trimming memory of heavy-weight " + app.processName
   18434                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   18435                             app.thread.scheduleTrimMemory(
   18436                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   18437                         } catch (RemoteException e) {
   18438                         }
   18439                     }
   18440                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   18441                 } else {
   18442                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   18443                             || app.systemNoUi) && app.pendingUiClean) {
   18444                         // If this application is now in the background and it
   18445                         // had done UI, then give it the special trim level to
   18446                         // have it free UI resources.
   18447                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   18448                         if (app.trimMemoryLevel < level && app.thread != null) {
   18449                             try {
   18450                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18451                                         "Trimming memory of bg-ui " + app.processName
   18452                                         + " to " + level);
   18453                                 app.thread.scheduleTrimMemory(level);
   18454                             } catch (RemoteException e) {
   18455                             }
   18456                         }
   18457                         app.pendingUiClean = false;
   18458                     }
   18459                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   18460                         try {
   18461                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18462                                     "Trimming memory of fg " + app.processName
   18463                                     + " to " + fgTrimLevel);
   18464                             app.thread.scheduleTrimMemory(fgTrimLevel);
   18465                         } catch (RemoteException e) {
   18466                         }
   18467                     }
   18468                     app.trimMemoryLevel = fgTrimLevel;
   18469                 }
   18470             }
   18471         } else {
   18472             if (mLowRamStartTime != 0) {
   18473                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   18474                 mLowRamStartTime = 0;
   18475             }
   18476             for (int i=N-1; i>=0; i--) {
   18477                 ProcessRecord app = mLruProcesses.get(i);
   18478                 if (allChanged || app.procStateChanged) {
   18479                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   18480                     app.procStateChanged = false;
   18481                 }
   18482                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   18483                         || app.systemNoUi) && app.pendingUiClean) {
   18484                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   18485                             && app.thread != null) {
   18486                         try {
   18487                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   18488                                     "Trimming memory of ui hidden " + app.processName
   18489                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   18490                             app.thread.scheduleTrimMemory(
   18491                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   18492                         } catch (RemoteException e) {
   18493                         }
   18494                     }
   18495                     app.pendingUiClean = false;
   18496                 }
   18497                 app.trimMemoryLevel = 0;
   18498             }
   18499         }
   18500 
   18501         if (mAlwaysFinishActivities) {
   18502             // Need to do this on its own message because the stack may not
   18503             // be in a consistent state at this point.
   18504             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   18505         }
   18506 
   18507         if (allChanged) {
   18508             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   18509         }
   18510 
   18511         if (mProcessStats.shouldWriteNowLocked(now)) {
   18512             mHandler.post(new Runnable() {
   18513                 @Override public void run() {
   18514                     synchronized (ActivityManagerService.this) {
   18515                         mProcessStats.writeStateAsyncLocked();
   18516                     }
   18517                 }
   18518             });
   18519         }
   18520 
   18521         if (DEBUG_OOM_ADJ) {
   18522             if (false) {
   18523                 RuntimeException here = new RuntimeException("here");
   18524                 here.fillInStackTrace();
   18525                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
   18526             } else {
   18527                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   18528             }
   18529         }
   18530     }
   18531 
   18532     final void trimApplications() {
   18533         synchronized (this) {
   18534             int i;
   18535 
   18536             // First remove any unused application processes whose package
   18537             // has been removed.
   18538             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   18539                 final ProcessRecord app = mRemovedProcesses.get(i);
   18540                 if (app.activities.size() == 0
   18541                         && app.curReceiver == null && app.services.size() == 0) {
   18542                     Slog.i(
   18543                         TAG, "Exiting empty application process "
   18544                         + app.processName + " ("
   18545                         + (app.thread != null ? app.thread.asBinder() : null)
   18546                         + ")\n");
   18547                     if (app.pid > 0 && app.pid != MY_PID) {
   18548                         app.kill("empty", false);
   18549                     } else {
   18550                         try {
   18551                             app.thread.scheduleExit();
   18552                         } catch (Exception e) {
   18553                             // Ignore exceptions.
   18554                         }
   18555                     }
   18556                     cleanUpApplicationRecordLocked(app, false, true, -1);
   18557                     mRemovedProcesses.remove(i);
   18558 
   18559                     if (app.persistent) {
   18560                         addAppLocked(app.info, false, null /* ABI override */);
   18561                     }
   18562                 }
   18563             }
   18564 
   18565             // Now update the oom adj for all processes.
   18566             updateOomAdjLocked();
   18567         }
   18568     }
   18569 
   18570     /** This method sends the specified signal to each of the persistent apps */
   18571     public void signalPersistentProcesses(int sig) throws RemoteException {
   18572         if (sig != Process.SIGNAL_USR1) {
   18573             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   18574         }
   18575 
   18576         synchronized (this) {
   18577             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   18578                     != PackageManager.PERMISSION_GRANTED) {
   18579                 throw new SecurityException("Requires permission "
   18580                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   18581             }
   18582 
   18583             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   18584                 ProcessRecord r = mLruProcesses.get(i);
   18585                 if (r.thread != null && r.persistent) {
   18586                     Process.sendSignal(r.pid, sig);
   18587                 }
   18588             }
   18589         }
   18590     }
   18591 
   18592     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   18593         if (proc == null || proc == mProfileProc) {
   18594             proc = mProfileProc;
   18595             profileType = mProfileType;
   18596             clearProfilerLocked();
   18597         }
   18598         if (proc == null) {
   18599             return;
   18600         }
   18601         try {
   18602             proc.thread.profilerControl(false, null, profileType);
   18603         } catch (RemoteException e) {
   18604             throw new IllegalStateException("Process disappeared");
   18605         }
   18606     }
   18607 
   18608     private void clearProfilerLocked() {
   18609         if (mProfileFd != null) {
   18610             try {
   18611                 mProfileFd.close();
   18612             } catch (IOException e) {
   18613             }
   18614         }
   18615         mProfileApp = null;
   18616         mProfileProc = null;
   18617         mProfileFile = null;
   18618         mProfileType = 0;
   18619         mAutoStopProfiler = false;
   18620         mSamplingInterval = 0;
   18621     }
   18622 
   18623     public boolean profileControl(String process, int userId, boolean start,
   18624             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   18625 
   18626         try {
   18627             synchronized (this) {
   18628                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18629                 // its own permission.
   18630                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18631                         != PackageManager.PERMISSION_GRANTED) {
   18632                     throw new SecurityException("Requires permission "
   18633                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18634                 }
   18635 
   18636                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   18637                     throw new IllegalArgumentException("null profile info or fd");
   18638                 }
   18639 
   18640                 ProcessRecord proc = null;
   18641                 if (process != null) {
   18642                     proc = findProcessLocked(process, userId, "profileControl");
   18643                 }
   18644 
   18645                 if (start && (proc == null || proc.thread == null)) {
   18646                     throw new IllegalArgumentException("Unknown process: " + process);
   18647                 }
   18648 
   18649                 if (start) {
   18650                     stopProfilerLocked(null, 0);
   18651                     setProfileApp(proc.info, proc.processName, profilerInfo);
   18652                     mProfileProc = proc;
   18653                     mProfileType = profileType;
   18654                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   18655                     try {
   18656                         fd = fd.dup();
   18657                     } catch (IOException e) {
   18658                         fd = null;
   18659                     }
   18660                     profilerInfo.profileFd = fd;
   18661                     proc.thread.profilerControl(start, profilerInfo, profileType);
   18662                     fd = null;
   18663                     mProfileFd = null;
   18664                 } else {
   18665                     stopProfilerLocked(proc, profileType);
   18666                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   18667                         try {
   18668                             profilerInfo.profileFd.close();
   18669                         } catch (IOException e) {
   18670                         }
   18671                     }
   18672                 }
   18673 
   18674                 return true;
   18675             }
   18676         } catch (RemoteException e) {
   18677             throw new IllegalStateException("Process disappeared");
   18678         } finally {
   18679             if (profilerInfo != null && profilerInfo.profileFd != null) {
   18680                 try {
   18681                     profilerInfo.profileFd.close();
   18682                 } catch (IOException e) {
   18683                 }
   18684             }
   18685         }
   18686     }
   18687 
   18688     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   18689         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18690                 userId, true, ALLOW_FULL_ONLY, callName, null);
   18691         ProcessRecord proc = null;
   18692         try {
   18693             int pid = Integer.parseInt(process);
   18694             synchronized (mPidsSelfLocked) {
   18695                 proc = mPidsSelfLocked.get(pid);
   18696             }
   18697         } catch (NumberFormatException e) {
   18698         }
   18699 
   18700         if (proc == null) {
   18701             ArrayMap<String, SparseArray<ProcessRecord>> all
   18702                     = mProcessNames.getMap();
   18703             SparseArray<ProcessRecord> procs = all.get(process);
   18704             if (procs != null && procs.size() > 0) {
   18705                 proc = procs.valueAt(0);
   18706                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   18707                     for (int i=1; i<procs.size(); i++) {
   18708                         ProcessRecord thisProc = procs.valueAt(i);
   18709                         if (thisProc.userId == userId) {
   18710                             proc = thisProc;
   18711                             break;
   18712                         }
   18713                     }
   18714                 }
   18715             }
   18716         }
   18717 
   18718         return proc;
   18719     }
   18720 
   18721     public boolean dumpHeap(String process, int userId, boolean managed,
   18722             String path, ParcelFileDescriptor fd) throws RemoteException {
   18723 
   18724         try {
   18725             synchronized (this) {
   18726                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18727                 // its own permission (same as profileControl).
   18728                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18729                         != PackageManager.PERMISSION_GRANTED) {
   18730                     throw new SecurityException("Requires permission "
   18731                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18732                 }
   18733 
   18734                 if (fd == null) {
   18735                     throw new IllegalArgumentException("null fd");
   18736                 }
   18737 
   18738                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   18739                 if (proc == null || proc.thread == null) {
   18740                     throw new IllegalArgumentException("Unknown process: " + process);
   18741                 }
   18742 
   18743                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   18744                 if (!isDebuggable) {
   18745                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   18746                         throw new SecurityException("Process not debuggable: " + proc);
   18747                     }
   18748                 }
   18749 
   18750                 proc.thread.dumpHeap(managed, path, fd);
   18751                 fd = null;
   18752                 return true;
   18753             }
   18754         } catch (RemoteException e) {
   18755             throw new IllegalStateException("Process disappeared");
   18756         } finally {
   18757             if (fd != null) {
   18758                 try {
   18759                     fd.close();
   18760                 } catch (IOException e) {
   18761                 }
   18762             }
   18763         }
   18764     }
   18765 
   18766     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   18767     public void monitor() {
   18768         synchronized (this) { }
   18769     }
   18770 
   18771     void onCoreSettingsChange(Bundle settings) {
   18772         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   18773             ProcessRecord processRecord = mLruProcesses.get(i);
   18774             try {
   18775                 if (processRecord.thread != null) {
   18776                     processRecord.thread.setCoreSettings(settings);
   18777                 }
   18778             } catch (RemoteException re) {
   18779                 /* ignore */
   18780             }
   18781         }
   18782     }
   18783 
   18784     // Multi-user methods
   18785 
   18786     /**
   18787      * Start user, if its not already running, but don't bring it to foreground.
   18788      */
   18789     @Override
   18790     public boolean startUserInBackground(final int userId) {
   18791         return startUser(userId, /* foreground */ false);
   18792     }
   18793 
   18794     /**
   18795      * Start user, if its not already running, and bring it to foreground.
   18796      */
   18797     boolean startUserInForeground(final int userId, Dialog dlg) {
   18798         boolean result = startUser(userId, /* foreground */ true);
   18799         dlg.dismiss();
   18800         return result;
   18801     }
   18802 
   18803     /**
   18804      * Refreshes the list of users related to the current user when either a
   18805      * user switch happens or when a new related user is started in the
   18806      * background.
   18807      */
   18808     private void updateCurrentProfileIdsLocked() {
   18809         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18810                 mCurrentUserId, false /* enabledOnly */);
   18811         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
   18812         for (int i = 0; i < currentProfileIds.length; i++) {
   18813             currentProfileIds[i] = profiles.get(i).id;
   18814         }
   18815         mCurrentProfileIds = currentProfileIds;
   18816 
   18817         synchronized (mUserProfileGroupIdsSelfLocked) {
   18818             mUserProfileGroupIdsSelfLocked.clear();
   18819             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
   18820             for (int i = 0; i < users.size(); i++) {
   18821                 UserInfo user = users.get(i);
   18822                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
   18823                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
   18824                 }
   18825             }
   18826         }
   18827     }
   18828 
   18829     private Set getProfileIdsLocked(int userId) {
   18830         Set userIds = new HashSet<Integer>();
   18831         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18832                 userId, false /* enabledOnly */);
   18833         for (UserInfo user : profiles) {
   18834             userIds.add(Integer.valueOf(user.id));
   18835         }
   18836         return userIds;
   18837     }
   18838 
   18839     @Override
   18840     public boolean switchUser(final int userId) {
   18841         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   18842         String userName;
   18843         synchronized (this) {
   18844             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18845             if (userInfo == null) {
   18846                 Slog.w(TAG, "No user info for user #" + userId);
   18847                 return false;
   18848             }
   18849             if (userInfo.isManagedProfile()) {
   18850                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18851                 return false;
   18852             }
   18853             userName = userInfo.name;
   18854             mTargetUserId = userId;
   18855         }
   18856         mHandler.removeMessages(START_USER_SWITCH_MSG);
   18857         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
   18858         return true;
   18859     }
   18860 
   18861     private void showUserSwitchDialog(int userId, String userName) {
   18862         // The dialog will show and then initiate the user switch by calling startUserInForeground
   18863         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
   18864                 true /* above system */);
   18865         d.show();
   18866     }
   18867 
   18868     private boolean startUser(final int userId, final boolean foreground) {
   18869         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18870                 != PackageManager.PERMISSION_GRANTED) {
   18871             String msg = "Permission Denial: switchUser() from pid="
   18872                     + Binder.getCallingPid()
   18873                     + ", uid=" + Binder.getCallingUid()
   18874                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   18875             Slog.w(TAG, msg);
   18876             throw new SecurityException(msg);
   18877         }
   18878 
   18879         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
   18880 
   18881         final long ident = Binder.clearCallingIdentity();
   18882         try {
   18883             synchronized (this) {
   18884                 final int oldUserId = mCurrentUserId;
   18885                 if (oldUserId == userId) {
   18886                     return true;
   18887                 }
   18888 
   18889                 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
   18890 
   18891                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18892                 if (userInfo == null) {
   18893                     Slog.w(TAG, "No user info for user #" + userId);
   18894                     return false;
   18895                 }
   18896                 if (foreground && userInfo.isManagedProfile()) {
   18897                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18898                     return false;
   18899                 }
   18900 
   18901                 if (foreground) {
   18902                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   18903                             R.anim.screen_user_enter);
   18904                 }
   18905 
   18906                 boolean needStart = false;
   18907 
   18908                 // If the user we are switching to is not currently started, then
   18909                 // we need to start it now.
   18910                 if (mStartedUsers.get(userId) == null) {
   18911                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   18912                     updateStartedUserArrayLocked();
   18913                     needStart = true;
   18914                 }
   18915 
   18916                 final Integer userIdInt = Integer.valueOf(userId);
   18917                 mUserLru.remove(userIdInt);
   18918                 mUserLru.add(userIdInt);
   18919 
   18920                 if (foreground) {
   18921                     mCurrentUserId = userId;
   18922                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
   18923                     updateCurrentProfileIdsLocked();
   18924                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
   18925                     // Once the internal notion of the active user has switched, we lock the device
   18926                     // with the option to show the user switcher on the keyguard.
   18927                     mWindowManager.lockNow(null);
   18928                 } else {
   18929                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
   18930                     updateCurrentProfileIdsLocked();
   18931                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
   18932                     mUserLru.remove(currentUserIdInt);
   18933                     mUserLru.add(currentUserIdInt);
   18934                 }
   18935 
   18936                 final UserStartedState uss = mStartedUsers.get(userId);
   18937 
   18938                 // Make sure user is in the started state.  If it is currently
   18939                 // stopping, we need to knock that off.
   18940                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   18941                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   18942                     // so we can just fairly silently bring the user back from
   18943                     // the almost-dead.
   18944                     uss.mState = UserStartedState.STATE_RUNNING;
   18945                     updateStartedUserArrayLocked();
   18946                     needStart = true;
   18947                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   18948                     // This means ACTION_SHUTDOWN has been sent, so we will
   18949                     // need to treat this as a new boot of the user.
   18950                     uss.mState = UserStartedState.STATE_BOOTING;
   18951                     updateStartedUserArrayLocked();
   18952                     needStart = true;
   18953                 }
   18954 
   18955                 if (uss.mState == UserStartedState.STATE_BOOTING) {
   18956                     // Booting up a new user, need to tell system services about it.
   18957                     // Note that this is on the same handler as scheduling of broadcasts,
   18958                     // which is important because it needs to go first.
   18959                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
   18960                 }
   18961 
   18962                 if (foreground) {
   18963                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
   18964                             oldUserId));
   18965                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   18966                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   18967                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   18968                             oldUserId, userId, uss));
   18969                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   18970                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   18971                 }
   18972 
   18973                 if (needStart) {
   18974                     // Send USER_STARTED broadcast
   18975                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   18976                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18977                             | Intent.FLAG_RECEIVER_FOREGROUND);
   18978                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18979                     broadcastIntentLocked(null, null, intent,
   18980                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18981                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   18982                 }
   18983 
   18984                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   18985                     if (userId != UserHandle.USER_OWNER) {
   18986                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   18987                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   18988                         broadcastIntentLocked(null, null, intent, null,
   18989                                 new IIntentReceiver.Stub() {
   18990                                     public void performReceive(Intent intent, int resultCode,
   18991                                             String data, Bundle extras, boolean ordered,
   18992                                             boolean sticky, int sendingUser) {
   18993                                         onUserInitialized(uss, foreground, oldUserId, userId);
   18994                                     }
   18995                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   18996                                 true, false, MY_PID, Process.SYSTEM_UID,
   18997                                 userId);
   18998                         uss.initializing = true;
   18999                     } else {
   19000                         getUserManagerLocked().makeInitialized(userInfo.id);
   19001                     }
   19002                 }
   19003 
   19004                 if (foreground) {
   19005                     if (!uss.initializing) {
   19006                         moveUserToForeground(uss, oldUserId, userId);
   19007                     }
   19008                 } else {
   19009                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
   19010                 }
   19011 
   19012                 if (needStart) {
   19013                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   19014                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19015                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19016                     broadcastIntentLocked(null, null, intent,
   19017                             null, new IIntentReceiver.Stub() {
   19018                                 @Override
   19019                                 public void performReceive(Intent intent, int resultCode, String data,
   19020                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   19021                                         throws RemoteException {
   19022                                 }
   19023                             }, 0, null, null,
   19024                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   19025                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19026                 }
   19027             }
   19028         } finally {
   19029             Binder.restoreCallingIdentity(ident);
   19030         }
   19031 
   19032         return true;
   19033     }
   19034 
   19035     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   19036         long ident = Binder.clearCallingIdentity();
   19037         try {
   19038             Intent intent;
   19039             if (oldUserId >= 0) {
   19040                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
   19041                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
   19042                 int count = profiles.size();
   19043                 for (int i = 0; i < count; i++) {
   19044                     int profileUserId = profiles.get(i).id;
   19045                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   19046                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19047                             | Intent.FLAG_RECEIVER_FOREGROUND);
   19048                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   19049                     broadcastIntentLocked(null, null, intent,
   19050                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19051                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   19052                 }
   19053             }
   19054             if (newUserId >= 0) {
   19055                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
   19056                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
   19057                 int count = profiles.size();
   19058                 for (int i = 0; i < count; i++) {
   19059                     int profileUserId = profiles.get(i).id;
   19060                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   19061                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19062                             | Intent.FLAG_RECEIVER_FOREGROUND);
   19063                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   19064                     broadcastIntentLocked(null, null, intent,
   19065                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   19066                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   19067                 }
   19068                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   19069                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   19070                         | Intent.FLAG_RECEIVER_FOREGROUND);
   19071                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   19072                 broadcastIntentLocked(null, null, intent,
   19073                         null, null, 0, null, null,
   19074                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   19075                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19076             }
   19077         } finally {
   19078             Binder.restoreCallingIdentity(ident);
   19079         }
   19080     }
   19081 
   19082     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   19083             final int newUserId) {
   19084         final int N = mUserSwitchObservers.beginBroadcast();
   19085         if (N > 0) {
   19086             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   19087                 int mCount = 0;
   19088                 @Override
   19089                 public void sendResult(Bundle data) throws RemoteException {
   19090                     synchronized (ActivityManagerService.this) {
   19091                         if (mCurUserSwitchCallback == this) {
   19092                             mCount++;
   19093                             if (mCount == N) {
   19094                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19095                             }
   19096                         }
   19097                     }
   19098                 }
   19099             };
   19100             synchronized (this) {
   19101                 uss.switching = true;
   19102                 mCurUserSwitchCallback = callback;
   19103             }
   19104             for (int i=0; i<N; i++) {
   19105                 try {
   19106                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   19107                             newUserId, callback);
   19108                 } catch (RemoteException e) {
   19109                 }
   19110             }
   19111         } else {
   19112             synchronized (this) {
   19113                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19114             }
   19115         }
   19116         mUserSwitchObservers.finishBroadcast();
   19117     }
   19118 
   19119     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   19120         synchronized (this) {
   19121             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   19122             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   19123         }
   19124     }
   19125 
   19126     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   19127         mCurUserSwitchCallback = null;
   19128         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   19129         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   19130                 oldUserId, newUserId, uss));
   19131     }
   19132 
   19133     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
   19134         synchronized (this) {
   19135             if (foreground) {
   19136                 moveUserToForeground(uss, oldUserId, newUserId);
   19137             }
   19138         }
   19139 
   19140         completeSwitchAndInitalize(uss, newUserId, true, false);
   19141     }
   19142 
   19143     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
   19144         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
   19145         if (homeInFront) {
   19146             startHomeActivityLocked(newUserId, "moveUserToFroreground");
   19147         } else {
   19148             mStackSupervisor.resumeTopActivitiesLocked();
   19149         }
   19150         EventLogTags.writeAmSwitchUser(newUserId);
   19151         getUserManagerLocked().userForeground(newUserId);
   19152         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
   19153     }
   19154 
   19155     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   19156         completeSwitchAndInitalize(uss, newUserId, false, true);
   19157     }
   19158 
   19159     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   19160             boolean clearInitializing, boolean clearSwitching) {
   19161         boolean unfrozen = false;
   19162         synchronized (this) {
   19163             if (clearInitializing) {
   19164                 uss.initializing = false;
   19165                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   19166             }
   19167             if (clearSwitching) {
   19168                 uss.switching = false;
   19169             }
   19170             if (!uss.switching && !uss.initializing) {
   19171                 mWindowManager.stopFreezingScreen();
   19172                 unfrozen = true;
   19173             }
   19174         }
   19175         if (unfrozen) {
   19176             final int N = mUserSwitchObservers.beginBroadcast();
   19177             for (int i=0; i<N; i++) {
   19178                 try {
   19179                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   19180                 } catch (RemoteException e) {
   19181                 }
   19182             }
   19183             mUserSwitchObservers.finishBroadcast();
   19184         }
   19185         stopGuestUserIfBackground();
   19186     }
   19187 
   19188     /**
   19189      * Stops the guest user if it has gone to the background.
   19190      */
   19191     private void stopGuestUserIfBackground() {
   19192         synchronized (this) {
   19193             final int num = mUserLru.size();
   19194             for (int i = 0; i < num; i++) {
   19195                 Integer oldUserId = mUserLru.get(i);
   19196                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   19197                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
   19198                         || oldUss.mState == UserStartedState.STATE_STOPPING
   19199                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   19200                     continue;
   19201                 }
   19202                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
   19203                 if (userInfo.isGuest()) {
   19204                     // This is a user to be stopped.
   19205                     stopUserLocked(oldUserId, null);
   19206                     break;
   19207                 }
   19208             }
   19209         }
   19210     }
   19211 
   19212     void scheduleStartProfilesLocked() {
   19213         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   19214             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   19215                     DateUtils.SECOND_IN_MILLIS);
   19216         }
   19217     }
   19218 
   19219     void startProfilesLocked() {
   19220         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
   19221         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   19222                 mCurrentUserId, false /* enabledOnly */);
   19223         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
   19224         for (UserInfo user : profiles) {
   19225             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
   19226                     && user.id != mCurrentUserId) {
   19227                 toStart.add(user);
   19228             }
   19229         }
   19230         final int n = toStart.size();
   19231         int i = 0;
   19232         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
   19233             startUserInBackground(toStart.get(i).id);
   19234         }
   19235         if (i < n) {
   19236             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
   19237         }
   19238     }
   19239 
   19240     void finishUserBoot(UserStartedState uss) {
   19241         synchronized (this) {
   19242             if (uss.mState == UserStartedState.STATE_BOOTING
   19243                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   19244                 uss.mState = UserStartedState.STATE_RUNNING;
   19245                 final int userId = uss.mHandle.getIdentifier();
   19246                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   19247                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19248                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   19249                 broadcastIntentLocked(null, null, intent,
   19250                         null, null, 0, null, null,
   19251                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   19252                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   19253             }
   19254         }
   19255     }
   19256 
   19257     void finishUserSwitch(UserStartedState uss) {
   19258         synchronized (this) {
   19259             finishUserBoot(uss);
   19260 
   19261             startProfilesLocked();
   19262 
   19263             int num = mUserLru.size();
   19264             int i = 0;
   19265             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   19266                 Integer oldUserId = mUserLru.get(i);
   19267                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   19268                 if (oldUss == null) {
   19269                     // Shouldn't happen, but be sane if it does.
   19270                     mUserLru.remove(i);
   19271                     num--;
   19272                     continue;
   19273                 }
   19274                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   19275                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   19276                     // This user is already stopping, doesn't count.
   19277                     num--;
   19278                     i++;
   19279                     continue;
   19280                 }
   19281                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   19282                     // Owner and current can't be stopped, but count as running.
   19283                     i++;
   19284                     continue;
   19285                 }
   19286                 // This is a user to be stopped.
   19287                 stopUserLocked(oldUserId, null);
   19288                 num--;
   19289                 i++;
   19290             }
   19291         }
   19292     }
   19293 
   19294     @Override
   19295     public int stopUser(final int userId, final IStopUserCallback callback) {
   19296         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19297                 != PackageManager.PERMISSION_GRANTED) {
   19298             String msg = "Permission Denial: switchUser() from pid="
   19299                     + Binder.getCallingPid()
   19300                     + ", uid=" + Binder.getCallingUid()
   19301                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   19302             Slog.w(TAG, msg);
   19303             throw new SecurityException(msg);
   19304         }
   19305         if (userId <= 0) {
   19306             throw new IllegalArgumentException("Can't stop primary user " + userId);
   19307         }
   19308         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   19309         synchronized (this) {
   19310             return stopUserLocked(userId, callback);
   19311         }
   19312     }
   19313 
   19314     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   19315         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
   19316         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
   19317             return ActivityManager.USER_OP_IS_CURRENT;
   19318         }
   19319 
   19320         final UserStartedState uss = mStartedUsers.get(userId);
   19321         if (uss == null) {
   19322             // User is not started, nothing to do...  but we do need to
   19323             // callback if requested.
   19324             if (callback != null) {
   19325                 mHandler.post(new Runnable() {
   19326                     @Override
   19327                     public void run() {
   19328                         try {
   19329                             callback.userStopped(userId);
   19330                         } catch (RemoteException e) {
   19331                         }
   19332                     }
   19333                 });
   19334             }
   19335             return ActivityManager.USER_OP_SUCCESS;
   19336         }
   19337 
   19338         if (callback != null) {
   19339             uss.mStopCallbacks.add(callback);
   19340         }
   19341 
   19342         if (uss.mState != UserStartedState.STATE_STOPPING
   19343                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19344             uss.mState = UserStartedState.STATE_STOPPING;
   19345             updateStartedUserArrayLocked();
   19346 
   19347             long ident = Binder.clearCallingIdentity();
   19348             try {
   19349                 // We are going to broadcast ACTION_USER_STOPPING and then
   19350                 // once that is done send a final ACTION_SHUTDOWN and then
   19351                 // stop the user.
   19352                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   19353                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   19354                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   19355                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   19356                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   19357                 // This is the result receiver for the final shutdown broadcast.
   19358                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   19359                     @Override
   19360                     public void performReceive(Intent intent, int resultCode, String data,
   19361                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   19362                         finishUserStop(uss);
   19363                     }
   19364                 };
   19365                 // This is the result receiver for the initial stopping broadcast.
   19366                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   19367                     @Override
   19368                     public void performReceive(Intent intent, int resultCode, String data,
   19369                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   19370                         // On to the next.
   19371                         synchronized (ActivityManagerService.this) {
   19372                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   19373                                 // Whoops, we are being started back up.  Abort, abort!
   19374                                 return;
   19375                             }
   19376                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   19377                         }
   19378                         mBatteryStatsService.noteEvent(
   19379                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
   19380                                 Integer.toString(userId), userId);
   19381                         mSystemServiceManager.stopUser(userId);
   19382                         broadcastIntentLocked(null, null, shutdownIntent,
   19383                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   19384                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   19385                     }
   19386                 };
   19387                 // Kick things off.
   19388                 broadcastIntentLocked(null, null, stoppingIntent,
   19389                         null, stoppingReceiver, 0, null, null,
   19390                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   19391                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   19392             } finally {
   19393                 Binder.restoreCallingIdentity(ident);
   19394             }
   19395         }
   19396 
   19397         return ActivityManager.USER_OP_SUCCESS;
   19398     }
   19399 
   19400     void finishUserStop(UserStartedState uss) {
   19401         final int userId = uss.mHandle.getIdentifier();
   19402         boolean stopped;
   19403         ArrayList<IStopUserCallback> callbacks;
   19404         synchronized (this) {
   19405             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   19406             if (mStartedUsers.get(userId) != uss) {
   19407                 stopped = false;
   19408             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19409                 stopped = false;
   19410             } else {
   19411                 stopped = true;
   19412                 // User can no longer run.
   19413                 mStartedUsers.remove(userId);
   19414                 mUserLru.remove(Integer.valueOf(userId));
   19415                 updateStartedUserArrayLocked();
   19416 
   19417                 // Clean up all state and processes associated with the user.
   19418                 // Kill all the processes for the user.
   19419                 forceStopUserLocked(userId, "finish user");
   19420             }
   19421 
   19422             // Explicitly remove the old information in mRecentTasks.
   19423             removeRecentTasksForUserLocked(userId);
   19424         }
   19425 
   19426         for (int i=0; i<callbacks.size(); i++) {
   19427             try {
   19428                 if (stopped) callbacks.get(i).userStopped(userId);
   19429                 else callbacks.get(i).userStopAborted(userId);
   19430             } catch (RemoteException e) {
   19431             }
   19432         }
   19433 
   19434         if (stopped) {
   19435             mSystemServiceManager.cleanupUser(userId);
   19436             synchronized (this) {
   19437                 mStackSupervisor.removeUserLocked(userId);
   19438             }
   19439         }
   19440     }
   19441 
   19442     @Override
   19443     public UserInfo getCurrentUser() {
   19444         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
   19445                 != PackageManager.PERMISSION_GRANTED) && (
   19446                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19447                 != PackageManager.PERMISSION_GRANTED)) {
   19448             String msg = "Permission Denial: getCurrentUser() from pid="
   19449                     + Binder.getCallingPid()
   19450                     + ", uid=" + Binder.getCallingUid()
   19451                     + " requires " + INTERACT_ACROSS_USERS;
   19452             Slog.w(TAG, msg);
   19453             throw new SecurityException(msg);
   19454         }
   19455         synchronized (this) {
   19456             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   19457             return getUserManagerLocked().getUserInfo(userId);
   19458         }
   19459     }
   19460 
   19461     int getCurrentUserIdLocked() {
   19462         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   19463     }
   19464 
   19465     @Override
   19466     public boolean isUserRunning(int userId, boolean orStopped) {
   19467         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   19468                 != PackageManager.PERMISSION_GRANTED) {
   19469             String msg = "Permission Denial: isUserRunning() from pid="
   19470                     + Binder.getCallingPid()
   19471                     + ", uid=" + Binder.getCallingUid()
   19472                     + " requires " + INTERACT_ACROSS_USERS;
   19473             Slog.w(TAG, msg);
   19474             throw new SecurityException(msg);
   19475         }
   19476         synchronized (this) {
   19477             return isUserRunningLocked(userId, orStopped);
   19478         }
   19479     }
   19480 
   19481     boolean isUserRunningLocked(int userId, boolean orStopped) {
   19482         UserStartedState state = mStartedUsers.get(userId);
   19483         if (state == null) {
   19484             return false;
   19485         }
   19486         if (orStopped) {
   19487             return true;
   19488         }
   19489         return state.mState != UserStartedState.STATE_STOPPING
   19490                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   19491     }
   19492 
   19493     @Override
   19494     public int[] getRunningUserIds() {
   19495         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   19496                 != PackageManager.PERMISSION_GRANTED) {
   19497             String msg = "Permission Denial: isUserRunning() from pid="
   19498                     + Binder.getCallingPid()
   19499                     + ", uid=" + Binder.getCallingUid()
   19500                     + " requires " + INTERACT_ACROSS_USERS;
   19501             Slog.w(TAG, msg);
   19502             throw new SecurityException(msg);
   19503         }
   19504         synchronized (this) {
   19505             return mStartedUserArray;
   19506         }
   19507     }
   19508 
   19509     private void updateStartedUserArrayLocked() {
   19510         int num = 0;
   19511         for (int i=0; i<mStartedUsers.size();  i++) {
   19512             UserStartedState uss = mStartedUsers.valueAt(i);
   19513             // This list does not include stopping users.
   19514             if (uss.mState != UserStartedState.STATE_STOPPING
   19515                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19516                 num++;
   19517             }
   19518         }
   19519         mStartedUserArray = new int[num];
   19520         num = 0;
   19521         for (int i=0; i<mStartedUsers.size();  i++) {
   19522             UserStartedState uss = mStartedUsers.valueAt(i);
   19523             if (uss.mState != UserStartedState.STATE_STOPPING
   19524                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   19525                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   19526                 num++;
   19527             }
   19528         }
   19529     }
   19530 
   19531     @Override
   19532     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   19533         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   19534                 != PackageManager.PERMISSION_GRANTED) {
   19535             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   19536                     + Binder.getCallingPid()
   19537                     + ", uid=" + Binder.getCallingUid()
   19538                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   19539             Slog.w(TAG, msg);
   19540             throw new SecurityException(msg);
   19541         }
   19542 
   19543         mUserSwitchObservers.register(observer);
   19544     }
   19545 
   19546     @Override
   19547     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   19548         mUserSwitchObservers.unregister(observer);
   19549     }
   19550 
   19551     private boolean userExists(int userId) {
   19552         if (userId == 0) {
   19553             return true;
   19554         }
   19555         UserManagerService ums = getUserManagerLocked();
   19556         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   19557     }
   19558 
   19559     int[] getUsersLocked() {
   19560         UserManagerService ums = getUserManagerLocked();
   19561         return ums != null ? ums.getUserIds() : new int[] { 0 };
   19562     }
   19563 
   19564     UserManagerService getUserManagerLocked() {
   19565         if (mUserManager == null) {
   19566             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   19567             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   19568         }
   19569         return mUserManager;
   19570     }
   19571 
   19572     private int applyUserId(int uid, int userId) {
   19573         return UserHandle.getUid(userId, uid);
   19574     }
   19575 
   19576     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   19577         if (info == null) return null;
   19578         ApplicationInfo newInfo = new ApplicationInfo(info);
   19579         newInfo.uid = applyUserId(info.uid, userId);
   19580         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   19581                 + info.packageName;
   19582         return newInfo;
   19583     }
   19584 
   19585     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   19586         if (aInfo == null
   19587                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   19588             return aInfo;
   19589         }
   19590 
   19591         ActivityInfo info = new ActivityInfo(aInfo);
   19592         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   19593         return info;
   19594     }
   19595 
   19596     private final class LocalService extends ActivityManagerInternal {
   19597         @Override
   19598         public void onWakefulnessChanged(int wakefulness) {
   19599             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
   19600         }
   19601 
   19602         @Override
   19603         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   19604                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   19605             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   19606                     processName, abiOverride, uid, crashHandler);
   19607         }
   19608     }
   19609 
   19610     /**
   19611      * An implementation of IAppTask, that allows an app to manage its own tasks via
   19612      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   19613      * only the process that calls getAppTasks() can call the AppTask methods.
   19614      */
   19615     class AppTaskImpl extends IAppTask.Stub {
   19616         private int mTaskId;
   19617         private int mCallingUid;
   19618 
   19619         public AppTaskImpl(int taskId, int callingUid) {
   19620             mTaskId = taskId;
   19621             mCallingUid = callingUid;
   19622         }
   19623 
   19624         private void checkCaller() {
   19625             if (mCallingUid != Binder.getCallingUid()) {
   19626                 throw new SecurityException("Caller " + mCallingUid
   19627                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   19628             }
   19629         }
   19630 
   19631         @Override
   19632         public void finishAndRemoveTask() {
   19633             checkCaller();
   19634 
   19635             synchronized (ActivityManagerService.this) {
   19636                 long origId = Binder.clearCallingIdentity();
   19637                 try {
   19638                     if (!removeTaskByIdLocked(mTaskId, false)) {
   19639                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19640                     }
   19641                 } finally {
   19642                     Binder.restoreCallingIdentity(origId);
   19643                 }
   19644             }
   19645         }
   19646 
   19647         @Override
   19648         public ActivityManager.RecentTaskInfo getTaskInfo() {
   19649             checkCaller();
   19650 
   19651             synchronized (ActivityManagerService.this) {
   19652                 long origId = Binder.clearCallingIdentity();
   19653                 try {
   19654                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19655                     if (tr == null) {
   19656                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19657                     }
   19658                     return createRecentTaskInfoFromTaskRecord(tr);
   19659                 } finally {
   19660                     Binder.restoreCallingIdentity(origId);
   19661                 }
   19662             }
   19663         }
   19664 
   19665         @Override
   19666         public void moveToFront() {
   19667             checkCaller();
   19668             // Will bring task to front if it already has a root activity.
   19669             startActivityFromRecentsInner(mTaskId, null);
   19670         }
   19671 
   19672         @Override
   19673         public int startActivity(IBinder whoThread, String callingPackage,
   19674                 Intent intent, String resolvedType, Bundle options) {
   19675             checkCaller();
   19676 
   19677             int callingUser = UserHandle.getCallingUserId();
   19678             TaskRecord tr;
   19679             IApplicationThread appThread;
   19680             synchronized (ActivityManagerService.this) {
   19681                 tr = recentTaskForIdLocked(mTaskId);
   19682                 if (tr == null) {
   19683                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19684                 }
   19685                 appThread = ApplicationThreadNative.asInterface(whoThread);
   19686                 if (appThread == null) {
   19687                     throw new IllegalArgumentException("Bad app thread " + appThread);
   19688                 }
   19689             }
   19690             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
   19691                     resolvedType, null, null, null, null, 0, 0, null, null,
   19692                     null, options, callingUser, null, tr);
   19693         }
   19694 
   19695         @Override
   19696         public void setExcludeFromRecents(boolean exclude) {
   19697             checkCaller();
   19698 
   19699             synchronized (ActivityManagerService.this) {
   19700                 long origId = Binder.clearCallingIdentity();
   19701                 try {
   19702                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19703                     if (tr == null) {
   19704                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19705                     }
   19706                     Intent intent = tr.getBaseIntent();
   19707                     if (exclude) {
   19708                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19709                     } else {
   19710                         intent.setFlags(intent.getFlags()
   19711                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19712                     }
   19713                 } finally {
   19714                     Binder.restoreCallingIdentity(origId);
   19715                 }
   19716             }
   19717         }
   19718     }
   19719 }
   19720