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 
     34 import android.Manifest;
     35 import android.app.AppOpsManager;
     36 import android.app.ApplicationThreadNative;
     37 import android.app.IActivityContainer;
     38 import android.app.IActivityContainerCallback;
     39 import android.app.IAppTask;
     40 import android.app.ProfilerInfo;
     41 import android.app.admin.DevicePolicyManager;
     42 import android.app.usage.UsageEvents;
     43 import android.app.usage.UsageStatsManagerInternal;
     44 import android.appwidget.AppWidgetManager;
     45 import android.content.res.Resources;
     46 import android.graphics.Bitmap;
     47 import android.graphics.Point;
     48 import android.graphics.Rect;
     49 import android.os.BatteryStats;
     50 import android.os.PersistableBundle;
     51 import android.os.storage.IMountService;
     52 import android.os.storage.StorageManager;
     53 import android.service.voice.IVoiceInteractionSession;
     54 import android.util.ArrayMap;
     55 import android.util.ArraySet;
     56 import android.util.SparseIntArray;
     57 
     58 import com.android.internal.R;
     59 import com.android.internal.annotations.GuardedBy;
     60 import com.android.internal.app.IAppOpsService;
     61 import com.android.internal.app.IVoiceInteractor;
     62 import com.android.internal.app.ProcessMap;
     63 import com.android.internal.app.ProcessStats;
     64 import com.android.internal.content.PackageMonitor;
     65 import com.android.internal.os.BackgroundThread;
     66 import com.android.internal.os.BatteryStatsImpl;
     67 import com.android.internal.os.ProcessCpuTracker;
     68 import com.android.internal.os.TransferPipe;
     69 import com.android.internal.os.Zygote;
     70 import com.android.internal.util.FastPrintWriter;
     71 import com.android.internal.util.FastXmlSerializer;
     72 import com.android.internal.util.MemInfoReader;
     73 import com.android.internal.util.Preconditions;
     74 import com.android.server.AppOpsService;
     75 import com.android.server.AttributeCache;
     76 import com.android.server.IntentResolver;
     77 import com.android.server.LocalServices;
     78 import com.android.server.ServiceThread;
     79 import com.android.server.SystemService;
     80 import com.android.server.SystemServiceManager;
     81 import com.android.server.Watchdog;
     82 import com.android.server.am.ActivityStack.ActivityState;
     83 import com.android.server.firewall.IntentFirewall;
     84 import com.android.server.pm.UserManagerService;
     85 import com.android.server.wm.AppTransition;
     86 import com.android.server.wm.WindowManagerService;
     87 import com.google.android.collect.Lists;
     88 import com.google.android.collect.Maps;
     89 
     90 import libcore.io.IoUtils;
     91 
     92 import org.xmlpull.v1.XmlPullParser;
     93 import org.xmlpull.v1.XmlPullParserException;
     94 import org.xmlpull.v1.XmlSerializer;
     95 
     96 import android.app.Activity;
     97 import android.app.ActivityManager;
     98 import android.app.ActivityManager.RunningTaskInfo;
     99 import android.app.ActivityManager.StackInfo;
    100 import android.app.ActivityManagerInternal;
    101 import android.app.ActivityManagerNative;
    102 import android.app.ActivityOptions;
    103 import android.app.ActivityThread;
    104 import android.app.AlertDialog;
    105 import android.app.AppGlobals;
    106 import android.app.ApplicationErrorReport;
    107 import android.app.Dialog;
    108 import android.app.IActivityController;
    109 import android.app.IApplicationThread;
    110 import android.app.IInstrumentationWatcher;
    111 import android.app.INotificationManager;
    112 import android.app.IProcessObserver;
    113 import android.app.IServiceConnection;
    114 import android.app.IStopUserCallback;
    115 import android.app.IUiAutomationConnection;
    116 import android.app.IUserSwitchObserver;
    117 import android.app.Instrumentation;
    118 import android.app.Notification;
    119 import android.app.NotificationManager;
    120 import android.app.PendingIntent;
    121 import android.app.backup.IBackupManager;
    122 import android.content.ActivityNotFoundException;
    123 import android.content.BroadcastReceiver;
    124 import android.content.ClipData;
    125 import android.content.ComponentCallbacks2;
    126 import android.content.ComponentName;
    127 import android.content.ContentProvider;
    128 import android.content.ContentResolver;
    129 import android.content.Context;
    130 import android.content.DialogInterface;
    131 import android.content.IContentProvider;
    132 import android.content.IIntentReceiver;
    133 import android.content.IIntentSender;
    134 import android.content.Intent;
    135 import android.content.IntentFilter;
    136 import android.content.IntentSender;
    137 import android.content.pm.ActivityInfo;
    138 import android.content.pm.ApplicationInfo;
    139 import android.content.pm.ConfigurationInfo;
    140 import android.content.pm.IPackageDataObserver;
    141 import android.content.pm.IPackageManager;
    142 import android.content.pm.InstrumentationInfo;
    143 import android.content.pm.PackageInfo;
    144 import android.content.pm.PackageManager;
    145 import android.content.pm.ParceledListSlice;
    146 import android.content.pm.UserInfo;
    147 import android.content.pm.PackageManager.NameNotFoundException;
    148 import android.content.pm.PathPermission;
    149 import android.content.pm.ProviderInfo;
    150 import android.content.pm.ResolveInfo;
    151 import android.content.pm.ServiceInfo;
    152 import android.content.res.CompatibilityInfo;
    153 import android.content.res.Configuration;
    154 import android.net.Proxy;
    155 import android.net.ProxyInfo;
    156 import android.net.Uri;
    157 import android.os.Binder;
    158 import android.os.Build;
    159 import android.os.Bundle;
    160 import android.os.Debug;
    161 import android.os.DropBoxManager;
    162 import android.os.Environment;
    163 import android.os.FactoryTest;
    164 import android.os.FileObserver;
    165 import android.os.FileUtils;
    166 import android.os.Handler;
    167 import android.os.IBinder;
    168 import android.os.IPermissionController;
    169 import android.os.IRemoteCallback;
    170 import android.os.IUserManager;
    171 import android.os.Looper;
    172 import android.os.Message;
    173 import android.os.Parcel;
    174 import android.os.ParcelFileDescriptor;
    175 import android.os.Process;
    176 import android.os.RemoteCallbackList;
    177 import android.os.RemoteException;
    178 import android.os.SELinux;
    179 import android.os.ServiceManager;
    180 import android.os.StrictMode;
    181 import android.os.SystemClock;
    182 import android.os.SystemProperties;
    183 import android.os.UpdateLock;
    184 import android.os.UserHandle;
    185 import android.os.UserManager;
    186 import android.provider.Settings;
    187 import android.text.format.DateUtils;
    188 import android.text.format.Time;
    189 import android.util.AtomicFile;
    190 import android.util.EventLog;
    191 import android.util.Log;
    192 import android.util.Pair;
    193 import android.util.PrintWriterPrinter;
    194 import android.util.Slog;
    195 import android.util.SparseArray;
    196 import android.util.TimeUtils;
    197 import android.util.Xml;
    198 import android.view.Gravity;
    199 import android.view.LayoutInflater;
    200 import android.view.View;
    201 import android.view.WindowManager;
    202 import dalvik.system.VMRuntime;
    203 
    204 import java.io.BufferedInputStream;
    205 import java.io.BufferedOutputStream;
    206 import java.io.DataInputStream;
    207 import java.io.DataOutputStream;
    208 import java.io.File;
    209 import java.io.FileDescriptor;
    210 import java.io.FileInputStream;
    211 import java.io.FileNotFoundException;
    212 import java.io.FileOutputStream;
    213 import java.io.IOException;
    214 import java.io.InputStreamReader;
    215 import java.io.PrintWriter;
    216 import java.io.StringWriter;
    217 import java.lang.ref.WeakReference;
    218 import java.util.ArrayList;
    219 import java.util.Arrays;
    220 import java.util.Collections;
    221 import java.util.Comparator;
    222 import java.util.HashMap;
    223 import java.util.HashSet;
    224 import java.util.Iterator;
    225 import java.util.List;
    226 import java.util.Locale;
    227 import java.util.Map;
    228 import java.util.Set;
    229 import java.util.concurrent.atomic.AtomicBoolean;
    230 import java.util.concurrent.atomic.AtomicLong;
    231 
    232 public final class ActivityManagerService extends ActivityManagerNative
    233         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    234 
    235     private static final String USER_DATA_DIR = "/data/user/";
    236     // File that stores last updated system version and called preboot receivers
    237     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
    238 
    239     static final String TAG = "ActivityManager";
    240     static final String TAG_MU = "ActivityManagerServiceMU";
    241     static final boolean DEBUG = false;
    242     static final boolean localLOGV = DEBUG;
    243     static final boolean DEBUG_BACKUP = localLOGV || false;
    244     static final boolean DEBUG_BROADCAST = localLOGV || false;
    245     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    246     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    247     static final boolean DEBUG_CLEANUP = localLOGV || false;
    248     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    249     static final boolean DEBUG_FOCUS = false;
    250     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
    251     static final boolean DEBUG_MU = localLOGV || false;
    252     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    253     static final boolean DEBUG_LRU = localLOGV || false;
    254     static final boolean DEBUG_PAUSE = localLOGV || false;
    255     static final boolean DEBUG_POWER = localLOGV || false;
    256     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    257     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    258     static final boolean DEBUG_PROCESSES = localLOGV || false;
    259     static final boolean DEBUG_PROVIDER = localLOGV || false;
    260     static final boolean DEBUG_RESULTS = localLOGV || false;
    261     static final boolean DEBUG_SERVICE = localLOGV || false;
    262     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    263     static final boolean DEBUG_STACK = localLOGV || false;
    264     static final boolean DEBUG_SWITCH = localLOGV || false;
    265     static final boolean DEBUG_TASKS = localLOGV || false;
    266     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    267     static final boolean DEBUG_TRANSITION = localLOGV || false;
    268     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    269     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    270     static final boolean DEBUG_VISBILITY = localLOGV || false;
    271     static final boolean DEBUG_PSS = localLOGV || false;
    272     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
    273     static final boolean DEBUG_RECENTS = localLOGV || false;
    274     static final boolean VALIDATE_TOKENS = false;
    275     static final boolean SHOW_ACTIVITY_START_TIME = true;
    276 
    277     // Control over CPU and battery monitoring.
    278     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    279     static final boolean MONITOR_CPU_USAGE = true;
    280     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    281     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    282     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    283 
    284     // The flags that are set for all calls we make to the package manager.
    285     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    286 
    287     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    288 
    289     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    290 
    291     // Maximum number recent bitmaps to keep in memory.
    292     static final int MAX_RECENT_BITMAPS = 5;
    293 
    294     // Amount of time after a call to stopAppSwitches() during which we will
    295     // prevent further untrusted switches from happening.
    296     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    297 
    298     // How long we wait for a launched process to attach to the activity manager
    299     // before we decide it's never going to come up for real.
    300     static final int PROC_START_TIMEOUT = 10*1000;
    301 
    302     // How long we wait for a launched process to attach to the activity manager
    303     // before we decide it's never going to come up for real, when the process was
    304     // started with a wrapper for instrumentation (such as Valgrind) because it
    305     // could take much longer than usual.
    306     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
    307 
    308     // How long to wait after going idle before forcing apps to GC.
    309     static final int GC_TIMEOUT = 5*1000;
    310 
    311     // The minimum amount of time between successive GC requests for a process.
    312     static final int GC_MIN_INTERVAL = 60*1000;
    313 
    314     // The minimum amount of time between successive PSS requests for a process.
    315     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    316 
    317     // The minimum amount of time between successive PSS requests for a process
    318     // when the request is due to the memory state being lowered.
    319     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    320 
    321     // The rate at which we check for apps using excessive power -- 15 mins.
    322     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    323 
    324     // The minimum sample duration we will allow before deciding we have
    325     // enough data on wake locks to start killing things.
    326     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    327 
    328     // The minimum sample duration we will allow before deciding we have
    329     // enough data on CPU usage to start killing things.
    330     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    331 
    332     // How long we allow a receiver to run before giving up on it.
    333     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    334     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    335 
    336     // How long we wait until we timeout on key dispatching.
    337     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    338 
    339     // How long we wait until we timeout on key dispatching during instrumentation.
    340     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    341 
    342     // Amount of time we wait for observers to handle a user switch before
    343     // giving up on them and unfreezing the screen.
    344     static final int USER_SWITCH_TIMEOUT = 2*1000;
    345 
    346     // Maximum number of users we allow to be running at a time.
    347     static final int MAX_RUNNING_USERS = 3;
    348 
    349     // How long to wait in getAssistContextExtras for the activity and foreground services
    350     // to respond with the result.
    351     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    352 
    353     // Maximum number of persisted Uri grants a package is allowed
    354     static final int MAX_PERSISTED_URI_GRANTS = 128;
    355 
    356     static final int MY_PID = Process.myPid();
    357 
    358     static final String[] EMPTY_STRING_ARRAY = new String[0];
    359 
    360     // How many bytes to write into the dropbox log before truncating
    361     static final int DROPBOX_MAX_SIZE = 256 * 1024;
    362 
    363     // Access modes for handleIncomingUser.
    364     static final int ALLOW_NON_FULL = 0;
    365     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
    366     static final int ALLOW_FULL_ONLY = 2;
    367 
    368     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
    369 
    370     /** All system services */
    371     SystemServiceManager mSystemServiceManager;
    372 
    373     /** Run all ActivityStacks through this */
    374     ActivityStackSupervisor mStackSupervisor;
    375 
    376     public IntentFirewall mIntentFirewall;
    377 
    378     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    379     // default actuion automatically.  Important for devices without direct input
    380     // devices.
    381     private boolean mShowDialogs = true;
    382 
    383     BroadcastQueue mFgBroadcastQueue;
    384     BroadcastQueue mBgBroadcastQueue;
    385     // Convenient for easy iteration over the queues. Foreground is first
    386     // so that dispatch of foreground broadcasts gets precedence.
    387     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    388 
    389     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    390         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    391         if (DEBUG_BACKGROUND_BROADCAST) {
    392             Slog.i(TAG, "Broadcast intent " + intent + " on "
    393                     + (isFg ? "foreground" : "background")
    394                     + " queue");
    395         }
    396         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    397     }
    398 
    399     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    400         for (BroadcastQueue queue : mBroadcastQueues) {
    401             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    402             if (r != null) {
    403                 return r;
    404             }
    405         }
    406         return null;
    407     }
    408 
    409     /**
    410      * Activity we have told the window manager to have key focus.
    411      */
    412     ActivityRecord mFocusedActivity = null;
    413 
    414     /**
    415      * List of intents that were used to start the most recent tasks.
    416      */
    417     ArrayList<TaskRecord> mRecentTasks;
    418     ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
    419 
    420     /**
    421      * For addAppTask: cached of the last activity component that was added.
    422      */
    423     ComponentName mLastAddedTaskComponent;
    424 
    425     /**
    426      * For addAppTask: cached of the last activity uid that was added.
    427      */
    428     int mLastAddedTaskUid;
    429 
    430     /**
    431      * For addAppTask: cached of the last ActivityInfo that was added.
    432      */
    433     ActivityInfo mLastAddedTaskActivity;
    434 
    435     public class PendingAssistExtras extends Binder implements Runnable {
    436         public final ActivityRecord activity;
    437         public final Bundle extras;
    438         public final Intent intent;
    439         public final String hint;
    440         public final int userHandle;
    441         public boolean haveResult = false;
    442         public Bundle result = null;
    443         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
    444                 String _hint, int _userHandle) {
    445             activity = _activity;
    446             extras = _extras;
    447             intent = _intent;
    448             hint = _hint;
    449             userHandle = _userHandle;
    450         }
    451         @Override
    452         public void run() {
    453             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    454             synchronized (this) {
    455                 haveResult = true;
    456                 notifyAll();
    457             }
    458         }
    459     }
    460 
    461     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    462             = new ArrayList<PendingAssistExtras>();
    463 
    464     /**
    465      * Process management.
    466      */
    467     final ProcessList mProcessList = new ProcessList();
    468 
    469     /**
    470      * All of the applications we currently have running organized by name.
    471      * The keys are strings of the application package name (as
    472      * returned by the package manager), and the keys are ApplicationRecord
    473      * objects.
    474      */
    475     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    476 
    477     /**
    478      * Tracking long-term execution of processes to look for abuse and other
    479      * bad app behavior.
    480      */
    481     final ProcessStatsService mProcessStats;
    482 
    483     /**
    484      * The currently running isolated processes.
    485      */
    486     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    487 
    488     /**
    489      * Counter for assigning isolated process uids, to avoid frequently reusing the
    490      * same ones.
    491      */
    492     int mNextIsolatedProcessUid = 0;
    493 
    494     /**
    495      * The currently running heavy-weight process, if any.
    496      */
    497     ProcessRecord mHeavyWeightProcess = null;
    498 
    499     /**
    500      * The last time that various processes have crashed.
    501      */
    502     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    503 
    504     /**
    505      * Information about a process that is currently marked as bad.
    506      */
    507     static final class BadProcessInfo {
    508         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
    509             this.time = time;
    510             this.shortMsg = shortMsg;
    511             this.longMsg = longMsg;
    512             this.stack = stack;
    513         }
    514 
    515         final long time;
    516         final String shortMsg;
    517         final String longMsg;
    518         final String stack;
    519     }
    520 
    521     /**
    522      * Set of applications that we consider to be bad, and will reject
    523      * incoming broadcasts from (which the user has no control over).
    524      * Processes are added to this set when they have crashed twice within
    525      * a minimum amount of time; they are removed from it when they are
    526      * later restarted (hopefully due to some user action).  The value is the
    527      * time it was added to the list.
    528      */
    529     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
    530 
    531     /**
    532      * All of the processes we currently have running organized by pid.
    533      * The keys are the pid running the application.
    534      *
    535      * <p>NOTE: This object is protected by its own lock, NOT the global
    536      * activity manager lock!
    537      */
    538     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    539 
    540     /**
    541      * All of the processes that have been forced to be foreground.  The key
    542      * is the pid of the caller who requested it (we hold a death
    543      * link on it).
    544      */
    545     abstract class ForegroundToken implements IBinder.DeathRecipient {
    546         int pid;
    547         IBinder token;
    548     }
    549     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    550 
    551     /**
    552      * List of records for processes that someone had tried to start before the
    553      * system was ready.  We don't start them at that point, but ensure they
    554      * are started by the time booting is complete.
    555      */
    556     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    557 
    558     /**
    559      * List of persistent applications that are in the process
    560      * of being started.
    561      */
    562     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    563 
    564     /**
    565      * Processes that are being forcibly torn down.
    566      */
    567     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    568 
    569     /**
    570      * List of running applications, sorted by recent usage.
    571      * The first entry in the list is the least recently used.
    572      */
    573     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    574 
    575     /**
    576      * Where in mLruProcesses that the processes hosting activities start.
    577      */
    578     int mLruProcessActivityStart = 0;
    579 
    580     /**
    581      * Where in mLruProcesses that the processes hosting services start.
    582      * This is after (lower index) than mLruProcessesActivityStart.
    583      */
    584     int mLruProcessServiceStart = 0;
    585 
    586     /**
    587      * List of processes that should gc as soon as things are idle.
    588      */
    589     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    590 
    591     /**
    592      * Processes we want to collect PSS data from.
    593      */
    594     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    595 
    596     /**
    597      * Last time we requested PSS data of all processes.
    598      */
    599     long mLastFullPssTime = SystemClock.uptimeMillis();
    600 
    601     /**
    602      * If set, the next time we collect PSS data we should do a full collection
    603      * with data from native processes and the kernel.
    604      */
    605     boolean mFullPssPending = false;
    606 
    607     /**
    608      * This is the process holding what we currently consider to be
    609      * the "home" activity.
    610      */
    611     ProcessRecord mHomeProcess;
    612 
    613     /**
    614      * This is the process holding the activity the user last visited that
    615      * is in a different process from the one they are currently in.
    616      */
    617     ProcessRecord mPreviousProcess;
    618 
    619     /**
    620      * The time at which the previous process was last visible.
    621      */
    622     long mPreviousProcessVisibleTime;
    623 
    624     /**
    625      * Which uses have been started, so are allowed to run code.
    626      */
    627     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    628 
    629     /**
    630      * LRU list of history of current users.  Most recently current is at the end.
    631      */
    632     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    633 
    634     /**
    635      * Constant array of the users that are currently started.
    636      */
    637     int[] mStartedUserArray = new int[] { 0 };
    638 
    639     /**
    640      * Registered observers of the user switching mechanics.
    641      */
    642     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    643             = new RemoteCallbackList<IUserSwitchObserver>();
    644 
    645     /**
    646      * Currently active user switch.
    647      */
    648     Object mCurUserSwitchCallback;
    649 
    650     /**
    651      * Packages that the user has asked to have run in screen size
    652      * compatibility mode instead of filling the screen.
    653      */
    654     final CompatModePackages mCompatModePackages;
    655 
    656     /**
    657      * Set of IntentSenderRecord objects that are currently active.
    658      */
    659     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    660             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    661 
    662     /**
    663      * Fingerprints (hashCode()) of stack traces that we've
    664      * already logged DropBox entries for.  Guarded by itself.  If
    665      * something (rogue user app) forces this over
    666      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    667      */
    668     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    669     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    670 
    671     /**
    672      * Strict Mode background batched logging state.
    673      *
    674      * The string buffer is guarded by itself, and its lock is also
    675      * used to determine if another batched write is already
    676      * in-flight.
    677      */
    678     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    679 
    680     /**
    681      * Keeps track of all IIntentReceivers that have been registered for
    682      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    683      * a ReceiverList.
    684      */
    685     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
    686             new HashMap<IBinder, ReceiverList>();
    687 
    688     /**
    689      * Resolver for broadcast intents to registered receivers.
    690      * Holds BroadcastFilter (subclass of IntentFilter).
    691      */
    692     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    693             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    694         @Override
    695         protected boolean allowFilterResult(
    696                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    697             IBinder target = filter.receiverList.receiver.asBinder();
    698             for (int i=dest.size()-1; i>=0; i--) {
    699                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    700                     return false;
    701                 }
    702             }
    703             return true;
    704         }
    705 
    706         @Override
    707         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    708             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    709                     || userId == filter.owningUserId) {
    710                 return super.newResult(filter, match, userId);
    711             }
    712             return null;
    713         }
    714 
    715         @Override
    716         protected BroadcastFilter[] newArray(int size) {
    717             return new BroadcastFilter[size];
    718         }
    719 
    720         @Override
    721         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    722             return packageName.equals(filter.packageName);
    723         }
    724     };
    725 
    726     /**
    727      * State of all active sticky broadcasts per user.  Keys are the action of the
    728      * sticky Intent, values are an ArrayList of all broadcasted intents with
    729      * that action (which should usually be one).  The SparseArray is keyed
    730      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    731      * for stickies that are sent to all users.
    732      */
    733     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    734             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    735 
    736     final ActiveServices mServices;
    737 
    738     /**
    739      * Backup/restore process management
    740      */
    741     String mBackupAppName = null;
    742     BackupRecord mBackupTarget = null;
    743 
    744     final ProviderMap mProviderMap;
    745 
    746     /**
    747      * List of content providers who have clients waiting for them.  The
    748      * application is currently being launched and the provider will be
    749      * removed from this list once it is published.
    750      */
    751     final ArrayList<ContentProviderRecord> mLaunchingProviders
    752             = new ArrayList<ContentProviderRecord>();
    753 
    754     /**
    755      * File storing persisted {@link #mGrantedUriPermissions}.
    756      */
    757     private final AtomicFile mGrantFile;
    758 
    759     /** XML constants used in {@link #mGrantFile} */
    760     private static final String TAG_URI_GRANTS = "uri-grants";
    761     private static final String TAG_URI_GRANT = "uri-grant";
    762     private static final String ATTR_USER_HANDLE = "userHandle";
    763     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
    764     private static final String ATTR_TARGET_USER_ID = "targetUserId";
    765     private static final String ATTR_SOURCE_PKG = "sourcePkg";
    766     private static final String ATTR_TARGET_PKG = "targetPkg";
    767     private static final String ATTR_URI = "uri";
    768     private static final String ATTR_MODE_FLAGS = "modeFlags";
    769     private static final String ATTR_CREATED_TIME = "createdTime";
    770     private static final String ATTR_PREFIX = "prefix";
    771 
    772     /**
    773      * Global set of specific {@link Uri} permissions that have been granted.
    774      * This optimized lookup structure maps from {@link UriPermission#targetUid}
    775      * to {@link UriPermission#uri} to {@link UriPermission}.
    776      */
    777     @GuardedBy("this")
    778     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
    779             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
    780 
    781     public static class GrantUri {
    782         public final int sourceUserId;
    783         public final Uri uri;
    784         public boolean prefix;
    785 
    786         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
    787             this.sourceUserId = sourceUserId;
    788             this.uri = uri;
    789             this.prefix = prefix;
    790         }
    791 
    792         @Override
    793         public int hashCode() {
    794             return toString().hashCode();
    795         }
    796 
    797         @Override
    798         public boolean equals(Object o) {
    799             if (o instanceof GrantUri) {
    800                 GrantUri other = (GrantUri) o;
    801                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
    802                         && prefix == other.prefix;
    803             }
    804             return false;
    805         }
    806 
    807         @Override
    808         public String toString() {
    809             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
    810             if (prefix) result += " [prefix]";
    811             return result;
    812         }
    813 
    814         public String toSafeString() {
    815             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
    816             if (prefix) result += " [prefix]";
    817             return result;
    818         }
    819 
    820         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
    821             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
    822                     ContentProvider.getUriWithoutUserId(uri), false);
    823         }
    824     }
    825 
    826     CoreSettingsObserver mCoreSettingsObserver;
    827 
    828     /**
    829      * Thread-local storage used to carry caller permissions over through
    830      * indirect content-provider access.
    831      */
    832     private class Identity {
    833         public int pid;
    834         public int uid;
    835 
    836         Identity(int _pid, int _uid) {
    837             pid = _pid;
    838             uid = _uid;
    839         }
    840     }
    841 
    842     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    843 
    844     /**
    845      * All information we have collected about the runtime performance of
    846      * any user id that can impact battery performance.
    847      */
    848     final BatteryStatsService mBatteryStatsService;
    849 
    850     /**
    851      * Information about component usage
    852      */
    853     UsageStatsManagerInternal mUsageStatsService;
    854 
    855     /**
    856      * Information about and control over application operations
    857      */
    858     final AppOpsService mAppOpsService;
    859 
    860     /**
    861      * Save recent tasks information across reboots.
    862      */
    863     final TaskPersister mTaskPersister;
    864 
    865     /**
    866      * Current configuration information.  HistoryRecord objects are given
    867      * a reference to this object to indicate which configuration they are
    868      * currently running in, so this object must be kept immutable.
    869      */
    870     Configuration mConfiguration = new Configuration();
    871 
    872     /**
    873      * Current sequencing integer of the configuration, for skipping old
    874      * configurations.
    875      */
    876     int mConfigurationSeq = 0;
    877 
    878     /**
    879      * Hardware-reported OpenGLES version.
    880      */
    881     final int GL_ES_VERSION;
    882 
    883     /**
    884      * List of initialization arguments to pass to all processes when binding applications to them.
    885      * For example, references to the commonly used services.
    886      */
    887     HashMap<String, IBinder> mAppBindArgs;
    888 
    889     /**
    890      * Temporary to avoid allocations.  Protected by main lock.
    891      */
    892     final StringBuilder mStringBuilder = new StringBuilder(256);
    893 
    894     /**
    895      * Used to control how we initialize the service.
    896      */
    897     ComponentName mTopComponent;
    898     String mTopAction = Intent.ACTION_MAIN;
    899     String mTopData;
    900     boolean mProcessesReady = false;
    901     boolean mSystemReady = false;
    902     boolean mBooting = false;
    903     boolean mCallFinishBooting = false;
    904     boolean mBootAnimationComplete = false;
    905     boolean mWaitingUpdate = false;
    906     boolean mDidUpdate = false;
    907     boolean mOnBattery = false;
    908     boolean mLaunchWarningShown = false;
    909 
    910     Context mContext;
    911 
    912     int mFactoryTest;
    913 
    914     boolean mCheckedForSetup;
    915 
    916     /**
    917      * The time at which we will allow normal application switches again,
    918      * after a call to {@link #stopAppSwitches()}.
    919      */
    920     long mAppSwitchesAllowedTime;
    921 
    922     /**
    923      * This is set to true after the first switch after mAppSwitchesAllowedTime
    924      * is set; any switches after that will clear the time.
    925      */
    926     boolean mDidAppSwitch;
    927 
    928     /**
    929      * Last time (in realtime) at which we checked for power usage.
    930      */
    931     long mLastPowerCheckRealtime;
    932 
    933     /**
    934      * Last time (in uptime) at which we checked for power usage.
    935      */
    936     long mLastPowerCheckUptime;
    937 
    938     /**
    939      * Set while we are wanting to sleep, to prevent any
    940      * activities from being started/resumed.
    941      */
    942     private boolean mSleeping = false;
    943 
    944     /**
    945      * Set while we are running a voice interaction.  This overrides
    946      * sleeping while it is active.
    947      */
    948     private boolean mRunningVoice = false;
    949 
    950     /**
    951      * State of external calls telling us if the device is asleep.
    952      */
    953     private boolean mWentToSleep = false;
    954 
    955     /**
    956      * State of external call telling us if the lock screen is shown.
    957      */
    958     private boolean mLockScreenShown = false;
    959 
    960     /**
    961      * Set if we are shutting down the system, similar to sleeping.
    962      */
    963     boolean mShuttingDown = false;
    964 
    965     /**
    966      * Current sequence id for oom_adj computation traversal.
    967      */
    968     int mAdjSeq = 0;
    969 
    970     /**
    971      * Current sequence id for process LRU updating.
    972      */
    973     int mLruSeq = 0;
    974 
    975     /**
    976      * Keep track of the non-cached/empty process we last found, to help
    977      * determine how to distribute cached/empty processes next time.
    978      */
    979     int mNumNonCachedProcs = 0;
    980 
    981     /**
    982      * Keep track of the number of cached hidden procs, to balance oom adj
    983      * distribution between those and empty procs.
    984      */
    985     int mNumCachedHiddenProcs = 0;
    986 
    987     /**
    988      * Keep track of the number of service processes we last found, to
    989      * determine on the next iteration which should be B services.
    990      */
    991     int mNumServiceProcs = 0;
    992     int mNewNumAServiceProcs = 0;
    993     int mNewNumServiceProcs = 0;
    994 
    995     /**
    996      * Allow the current computed overall memory level of the system to go down?
    997      * This is set to false when we are killing processes for reasons other than
    998      * memory management, so that the now smaller process list will not be taken as
    999      * an indication that memory is tighter.
   1000      */
   1001     boolean mAllowLowerMemLevel = false;
   1002 
   1003     /**
   1004      * The last computed memory level, for holding when we are in a state that
   1005      * processes are going away for other reasons.
   1006      */
   1007     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   1008 
   1009     /**
   1010      * The last total number of process we have, to determine if changes actually look
   1011      * like a shrinking number of process due to lower RAM.
   1012      */
   1013     int mLastNumProcesses;
   1014 
   1015     /**
   1016      * The uptime of the last time we performed idle maintenance.
   1017      */
   1018     long mLastIdleTime = SystemClock.uptimeMillis();
   1019 
   1020     /**
   1021      * Total time spent with RAM that has been added in the past since the last idle time.
   1022      */
   1023     long mLowRamTimeSinceLastIdle = 0;
   1024 
   1025     /**
   1026      * If RAM is currently low, when that horrible situation started.
   1027      */
   1028     long mLowRamStartTime = 0;
   1029 
   1030     /**
   1031      * For reporting to battery stats the current top application.
   1032      */
   1033     private String mCurResumedPackage = null;
   1034     private int mCurResumedUid = -1;
   1035 
   1036     /**
   1037      * For reporting to battery stats the apps currently running foreground
   1038      * service.  The ProcessMap is package/uid tuples; each of these contain
   1039      * an array of the currently foreground processes.
   1040      */
   1041     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
   1042             = new ProcessMap<ArrayList<ProcessRecord>>();
   1043 
   1044     /**
   1045      * This is set if we had to do a delayed dexopt of an app before launching
   1046      * it, to increase the ANR timeouts in that case.
   1047      */
   1048     boolean mDidDexOpt;
   1049 
   1050     /**
   1051      * Set if the systemServer made a call to enterSafeMode.
   1052      */
   1053     boolean mSafeMode;
   1054 
   1055     String mDebugApp = null;
   1056     boolean mWaitForDebugger = false;
   1057     boolean mDebugTransient = false;
   1058     String mOrigDebugApp = null;
   1059     boolean mOrigWaitForDebugger = false;
   1060     boolean mAlwaysFinishActivities = false;
   1061     IActivityController mController = null;
   1062     String mProfileApp = null;
   1063     ProcessRecord mProfileProc = null;
   1064     String mProfileFile;
   1065     ParcelFileDescriptor mProfileFd;
   1066     int mSamplingInterval = 0;
   1067     boolean mAutoStopProfiler = false;
   1068     int mProfileType = 0;
   1069     String mOpenGlTraceApp = null;
   1070 
   1071     static class ProcessChangeItem {
   1072         static final int CHANGE_ACTIVITIES = 1<<0;
   1073         static final int CHANGE_PROCESS_STATE = 1<<1;
   1074         int changes;
   1075         int uid;
   1076         int pid;
   1077         int processState;
   1078         boolean foregroundActivities;
   1079     }
   1080 
   1081     final RemoteCallbackList<IProcessObserver> mProcessObservers
   1082             = new RemoteCallbackList<IProcessObserver>();
   1083     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
   1084 
   1085     final ArrayList<ProcessChangeItem> mPendingProcessChanges
   1086             = new ArrayList<ProcessChangeItem>();
   1087     final ArrayList<ProcessChangeItem> mAvailProcessChanges
   1088             = new ArrayList<ProcessChangeItem>();
   1089 
   1090     /**
   1091      * Runtime CPU use collection thread.  This object's lock is used to
   1092      * perform synchronization with the thread (notifying it to run).
   1093      */
   1094     final Thread mProcessCpuThread;
   1095 
   1096     /**
   1097      * Used to collect per-process CPU use for ANRs, battery stats, etc.
   1098      * Must acquire this object's lock when accessing it.
   1099      * NOTE: this lock will be held while doing long operations (trawling
   1100      * through all processes in /proc), so it should never be acquired by
   1101      * any critical paths such as when holding the main activity manager lock.
   1102      */
   1103     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
   1104             MONITOR_THREAD_CPU_USAGE);
   1105     final AtomicLong mLastCpuTime = new AtomicLong(0);
   1106     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
   1107 
   1108     long mLastWriteTime = 0;
   1109 
   1110     /**
   1111      * Used to retain an update lock when the foreground activity is in
   1112      * immersive mode.
   1113      */
   1114     final UpdateLock mUpdateLock = new UpdateLock("immersive");
   1115 
   1116     /**
   1117      * Set to true after the system has finished booting.
   1118      */
   1119     boolean mBooted = false;
   1120 
   1121     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
   1122     int mProcessLimitOverride = -1;
   1123 
   1124     WindowManagerService mWindowManager;
   1125 
   1126     final ActivityThread mSystemThread;
   1127 
   1128     // Holds the current foreground user's id
   1129     int mCurrentUserId = 0;
   1130     // Holds the target user's id during a user switch
   1131     int mTargetUserId = UserHandle.USER_NULL;
   1132     // If there are multiple profiles for the current user, their ids are here
   1133     // Currently only the primary user can have managed profiles
   1134     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
   1135 
   1136     /**
   1137      * Mapping from each known user ID to the profile group ID it is associated with.
   1138      */
   1139     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
   1140 
   1141     private UserManagerService mUserManager;
   1142 
   1143     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1144         final ProcessRecord mApp;
   1145         final int mPid;
   1146         final IApplicationThread mAppThread;
   1147 
   1148         AppDeathRecipient(ProcessRecord app, int pid,
   1149                 IApplicationThread thread) {
   1150             if (localLOGV) Slog.v(
   1151                 TAG, "New death recipient " + this
   1152                 + " for thread " + thread.asBinder());
   1153             mApp = app;
   1154             mPid = pid;
   1155             mAppThread = thread;
   1156         }
   1157 
   1158         @Override
   1159         public void binderDied() {
   1160             if (localLOGV) Slog.v(
   1161                 TAG, "Death received in " + this
   1162                 + " for thread " + mAppThread.asBinder());
   1163             synchronized(ActivityManagerService.this) {
   1164                 appDiedLocked(mApp, mPid, mAppThread);
   1165             }
   1166         }
   1167     }
   1168 
   1169     static final int SHOW_ERROR_MSG = 1;
   1170     static final int SHOW_NOT_RESPONDING_MSG = 2;
   1171     static final int SHOW_FACTORY_ERROR_MSG = 3;
   1172     static final int UPDATE_CONFIGURATION_MSG = 4;
   1173     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1174     static final int WAIT_FOR_DEBUGGER_MSG = 6;
   1175     static final int SERVICE_TIMEOUT_MSG = 12;
   1176     static final int UPDATE_TIME_ZONE = 13;
   1177     static final int SHOW_UID_ERROR_MSG = 14;
   1178     static final int IM_FEELING_LUCKY_MSG = 15;
   1179     static final int PROC_START_TIMEOUT_MSG = 20;
   1180     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1181     static final int KILL_APPLICATION_MSG = 22;
   1182     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1183     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1184     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1185     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
   1186     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1187     static final int CLEAR_DNS_CACHE_MSG = 28;
   1188     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1189     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
   1190     static final int DISPATCH_PROCESSES_CHANGED = 31;
   1191     static final int DISPATCH_PROCESS_DIED = 32;
   1192     static final int REPORT_MEM_USAGE_MSG = 33;
   1193     static final int REPORT_USER_SWITCH_MSG = 34;
   1194     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1195     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1196     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1197     static final int PERSIST_URI_GRANTS_MSG = 38;
   1198     static final int REQUEST_ALL_PSS_MSG = 39;
   1199     static final int START_PROFILES_MSG = 40;
   1200     static final int UPDATE_TIME = 41;
   1201     static final int SYSTEM_USER_START_MSG = 42;
   1202     static final int SYSTEM_USER_CURRENT_MSG = 43;
   1203     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
   1204     static final int FINISH_BOOTING_MSG = 45;
   1205     static final int START_USER_SWITCH_MSG = 46;
   1206     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
   1207 
   1208     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1209     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1210     static final int FIRST_COMPAT_MODE_MSG = 300;
   1211     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1212 
   1213     AlertDialog mUidAlert;
   1214     CompatModeDialog mCompatModeDialog;
   1215     long mLastMemUsageReportTime = 0;
   1216 
   1217     private LockToAppRequestDialog mLockToAppRequest;
   1218 
   1219     /**
   1220      * Flag whether the current user is a "monkey", i.e. whether
   1221      * the UI is driven by a UI automation tool.
   1222      */
   1223     private boolean mUserIsMonkey;
   1224 
   1225     /** Flag whether the device has a Recents UI */
   1226     boolean mHasRecents;
   1227 
   1228     /** The dimensions of the thumbnails in the Recents UI. */
   1229     int mThumbnailWidth;
   1230     int mThumbnailHeight;
   1231 
   1232     final ServiceThread mHandlerThread;
   1233     final MainHandler mHandler;
   1234 
   1235     final class MainHandler extends Handler {
   1236         public MainHandler(Looper looper) {
   1237             super(looper, null, true);
   1238         }
   1239 
   1240         @Override
   1241         public void handleMessage(Message msg) {
   1242             switch (msg.what) {
   1243             case SHOW_ERROR_MSG: {
   1244                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1245                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   1246                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   1247                 synchronized (ActivityManagerService.this) {
   1248                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1249                     AppErrorResult res = (AppErrorResult) data.get("result");
   1250                     if (proc != null && proc.crashDialog != null) {
   1251                         Slog.e(TAG, "App already has crash dialog: " + proc);
   1252                         if (res != null) {
   1253                             res.set(0);
   1254                         }
   1255                         return;
   1256                     }
   1257                     boolean isBackground = (UserHandle.getAppId(proc.uid)
   1258                             >= Process.FIRST_APPLICATION_UID
   1259                             && proc.pid != MY_PID);
   1260                     for (int userId : mCurrentProfileIds) {
   1261                         isBackground &= (proc.userId != userId);
   1262                     }
   1263                     if (isBackground && !showBackground) {
   1264                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
   1265                         if (res != null) {
   1266                             res.set(0);
   1267                         }
   1268                         return;
   1269                     }
   1270                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1271                         Dialog d = new AppErrorDialog(mContext,
   1272                                 ActivityManagerService.this, res, proc);
   1273                         d.show();
   1274                         proc.crashDialog = d;
   1275                     } else {
   1276                         // The device is asleep, so just pretend that the user
   1277                         // saw a crash dialog and hit "force quit".
   1278                         if (res != null) {
   1279                             res.set(0);
   1280                         }
   1281                     }
   1282                 }
   1283 
   1284                 ensureBootCompleted();
   1285             } break;
   1286             case SHOW_NOT_RESPONDING_MSG: {
   1287                 synchronized (ActivityManagerService.this) {
   1288                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1289                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1290                     if (proc != null && proc.anrDialog != null) {
   1291                         Slog.e(TAG, "App already has anr dialog: " + proc);
   1292                         return;
   1293                     }
   1294 
   1295                     Intent intent = new Intent("android.intent.action.ANR");
   1296                     if (!mProcessesReady) {
   1297                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   1298                                 | Intent.FLAG_RECEIVER_FOREGROUND);
   1299                     }
   1300                     broadcastIntentLocked(null, null, intent,
   1301                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   1302                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   1303 
   1304                     if (mShowDialogs) {
   1305                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1306                                 mContext, proc, (ActivityRecord)data.get("activity"),
   1307                                 msg.arg1 != 0);
   1308                         d.show();
   1309                         proc.anrDialog = d;
   1310                     } else {
   1311                         // Just kill the app if there is no dialog to be shown.
   1312                         killAppAtUsersRequest(proc, null);
   1313                     }
   1314                 }
   1315 
   1316                 ensureBootCompleted();
   1317             } break;
   1318             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1319                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1320                 synchronized (ActivityManagerService.this) {
   1321                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1322                     if (proc == null) {
   1323                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1324                         break;
   1325                     }
   1326                     if (proc.crashDialog != null) {
   1327                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1328                         return;
   1329                     }
   1330                     AppErrorResult res = (AppErrorResult) data.get("result");
   1331                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1332                         Dialog d = new StrictModeViolationDialog(mContext,
   1333                                 ActivityManagerService.this, res, proc);
   1334                         d.show();
   1335                         proc.crashDialog = d;
   1336                     } else {
   1337                         // The device is asleep, so just pretend that the user
   1338                         // saw a crash dialog and hit "force quit".
   1339                         res.set(0);
   1340                     }
   1341                 }
   1342                 ensureBootCompleted();
   1343             } break;
   1344             case SHOW_FACTORY_ERROR_MSG: {
   1345                 Dialog d = new FactoryErrorDialog(
   1346                     mContext, msg.getData().getCharSequence("msg"));
   1347                 d.show();
   1348                 ensureBootCompleted();
   1349             } break;
   1350             case UPDATE_CONFIGURATION_MSG: {
   1351                 final ContentResolver resolver = mContext.getContentResolver();
   1352                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1353             } break;
   1354             case GC_BACKGROUND_PROCESSES_MSG: {
   1355                 synchronized (ActivityManagerService.this) {
   1356                     performAppGcsIfAppropriateLocked();
   1357                 }
   1358             } break;
   1359             case WAIT_FOR_DEBUGGER_MSG: {
   1360                 synchronized (ActivityManagerService.this) {
   1361                     ProcessRecord app = (ProcessRecord)msg.obj;
   1362                     if (msg.arg1 != 0) {
   1363                         if (!app.waitedForDebugger) {
   1364                             Dialog d = new AppWaitingForDebuggerDialog(
   1365                                     ActivityManagerService.this,
   1366                                     mContext, app);
   1367                             app.waitDialog = d;
   1368                             app.waitedForDebugger = true;
   1369                             d.show();
   1370                         }
   1371                     } else {
   1372                         if (app.waitDialog != null) {
   1373                             app.waitDialog.dismiss();
   1374                             app.waitDialog = null;
   1375                         }
   1376                     }
   1377                 }
   1378             } break;
   1379             case SERVICE_TIMEOUT_MSG: {
   1380                 if (mDidDexOpt) {
   1381                     mDidDexOpt = false;
   1382                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1383                     nmsg.obj = msg.obj;
   1384                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1385                     return;
   1386                 }
   1387                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1388             } break;
   1389             case UPDATE_TIME_ZONE: {
   1390                 synchronized (ActivityManagerService.this) {
   1391                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1392                         ProcessRecord r = mLruProcesses.get(i);
   1393                         if (r.thread != null) {
   1394                             try {
   1395                                 r.thread.updateTimeZone();
   1396                             } catch (RemoteException ex) {
   1397                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1398                             }
   1399                         }
   1400                     }
   1401                 }
   1402             } break;
   1403             case CLEAR_DNS_CACHE_MSG: {
   1404                 synchronized (ActivityManagerService.this) {
   1405                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1406                         ProcessRecord r = mLruProcesses.get(i);
   1407                         if (r.thread != null) {
   1408                             try {
   1409                                 r.thread.clearDnsCache();
   1410                             } catch (RemoteException ex) {
   1411                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1412                             }
   1413                         }
   1414                     }
   1415                 }
   1416             } break;
   1417             case UPDATE_HTTP_PROXY_MSG: {
   1418                 ProxyInfo proxy = (ProxyInfo)msg.obj;
   1419                 String host = "";
   1420                 String port = "";
   1421                 String exclList = "";
   1422                 Uri pacFileUrl = Uri.EMPTY;
   1423                 if (proxy != null) {
   1424                     host = proxy.getHost();
   1425                     port = Integer.toString(proxy.getPort());
   1426                     exclList = proxy.getExclusionListAsString();
   1427                     pacFileUrl = proxy.getPacFileUrl();
   1428                 }
   1429                 synchronized (ActivityManagerService.this) {
   1430                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1431                         ProcessRecord r = mLruProcesses.get(i);
   1432                         if (r.thread != null) {
   1433                             try {
   1434                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1435                             } catch (RemoteException ex) {
   1436                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1437                                         r.info.processName);
   1438                             }
   1439                         }
   1440                     }
   1441                 }
   1442             } break;
   1443             case SHOW_UID_ERROR_MSG: {
   1444                 String title = "System UIDs Inconsistent";
   1445                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1446                         + " data partition or your device will be unstable.";
   1447                 Log.e(TAG, title + ": " + text);
   1448                 if (mShowDialogs) {
   1449                     // XXX This is a temporary dialog, no need to localize.
   1450                     AlertDialog d = new BaseErrorDialog(mContext);
   1451                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1452                     d.setCancelable(false);
   1453                     d.setTitle(title);
   1454                     d.setMessage(text);
   1455                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1456                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1457                     mUidAlert = d;
   1458                     d.show();
   1459                 }
   1460             } break;
   1461             case IM_FEELING_LUCKY_MSG: {
   1462                 if (mUidAlert != null) {
   1463                     mUidAlert.dismiss();
   1464                     mUidAlert = null;
   1465                 }
   1466             } break;
   1467             case PROC_START_TIMEOUT_MSG: {
   1468                 if (mDidDexOpt) {
   1469                     mDidDexOpt = false;
   1470                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1471                     nmsg.obj = msg.obj;
   1472                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1473                     return;
   1474                 }
   1475                 ProcessRecord app = (ProcessRecord)msg.obj;
   1476                 synchronized (ActivityManagerService.this) {
   1477                     processStartTimedOutLocked(app);
   1478                 }
   1479             } break;
   1480             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1481                 synchronized (ActivityManagerService.this) {
   1482                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
   1483                 }
   1484             } break;
   1485             case KILL_APPLICATION_MSG: {
   1486                 synchronized (ActivityManagerService.this) {
   1487                     int appid = msg.arg1;
   1488                     boolean restart = (msg.arg2 == 1);
   1489                     Bundle bundle = (Bundle)msg.obj;
   1490                     String pkg = bundle.getString("pkg");
   1491                     String reason = bundle.getString("reason");
   1492                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1493                             false, UserHandle.USER_ALL, reason);
   1494                 }
   1495             } break;
   1496             case FINALIZE_PENDING_INTENT_MSG: {
   1497                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1498             } break;
   1499             case POST_HEAVY_NOTIFICATION_MSG: {
   1500                 INotificationManager inm = NotificationManager.getService();
   1501                 if (inm == null) {
   1502                     return;
   1503                 }
   1504 
   1505                 ActivityRecord root = (ActivityRecord)msg.obj;
   1506                 ProcessRecord process = root.app;
   1507                 if (process == null) {
   1508                     return;
   1509                 }
   1510 
   1511                 try {
   1512                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1513                     String text = mContext.getString(R.string.heavy_weight_notification,
   1514                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1515                     Notification notification = new Notification();
   1516                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1517                     notification.when = 0;
   1518                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1519                     notification.tickerText = text;
   1520                     notification.defaults = 0; // please be quiet
   1521                     notification.sound = null;
   1522                     notification.vibrate = null;
   1523                     notification.color = mContext.getResources().getColor(
   1524                             com.android.internal.R.color.system_notification_accent_color);
   1525                     notification.setLatestEventInfo(context, text,
   1526                             mContext.getText(R.string.heavy_weight_notification_detail),
   1527                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1528                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1529                                     new UserHandle(root.userId)));
   1530 
   1531                     try {
   1532                         int[] outId = new int[1];
   1533                         inm.enqueueNotificationWithTag("android", "android", null,
   1534                                 R.string.heavy_weight_notification,
   1535                                 notification, outId, root.userId);
   1536                     } catch (RuntimeException e) {
   1537                         Slog.w(ActivityManagerService.TAG,
   1538                                 "Error showing notification for heavy-weight app", e);
   1539                     } catch (RemoteException e) {
   1540                     }
   1541                 } catch (NameNotFoundException e) {
   1542                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1543                 }
   1544             } break;
   1545             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1546                 INotificationManager inm = NotificationManager.getService();
   1547                 if (inm == null) {
   1548                     return;
   1549                 }
   1550                 try {
   1551                     inm.cancelNotificationWithTag("android", null,
   1552                             R.string.heavy_weight_notification,  msg.arg1);
   1553                 } catch (RuntimeException e) {
   1554                     Slog.w(ActivityManagerService.TAG,
   1555                             "Error canceling notification for service", e);
   1556                 } catch (RemoteException e) {
   1557                 }
   1558             } break;
   1559             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1560                 synchronized (ActivityManagerService.this) {
   1561                     checkExcessivePowerUsageLocked(true);
   1562                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1563                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1564                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1565                 }
   1566             } break;
   1567             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1568                 synchronized (ActivityManagerService.this) {
   1569                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1570                     if (mCompatModeDialog != null) {
   1571                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1572                                 ar.info.applicationInfo.packageName)) {
   1573                             return;
   1574                         }
   1575                         mCompatModeDialog.dismiss();
   1576                         mCompatModeDialog = null;
   1577                     }
   1578                     if (ar != null && false) {
   1579                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1580                                 ar.packageName)) {
   1581                             int mode = mCompatModePackages.computeCompatModeLocked(
   1582                                     ar.info.applicationInfo);
   1583                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1584                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1585                                 mCompatModeDialog = new CompatModeDialog(
   1586                                         ActivityManagerService.this, mContext,
   1587                                         ar.info.applicationInfo);
   1588                                 mCompatModeDialog.show();
   1589                             }
   1590                         }
   1591                     }
   1592                 }
   1593                 break;
   1594             }
   1595             case DISPATCH_PROCESSES_CHANGED: {
   1596                 dispatchProcessesChanged();
   1597                 break;
   1598             }
   1599             case DISPATCH_PROCESS_DIED: {
   1600                 final int pid = msg.arg1;
   1601                 final int uid = msg.arg2;
   1602                 dispatchProcessDied(pid, uid);
   1603                 break;
   1604             }
   1605             case REPORT_MEM_USAGE_MSG: {
   1606                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1607                 Thread thread = new Thread() {
   1608                     @Override public void run() {
   1609                         final SparseArray<ProcessMemInfo> infoMap
   1610                                 = new SparseArray<ProcessMemInfo>(memInfos.size());
   1611                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1612                             ProcessMemInfo mi = memInfos.get(i);
   1613                             infoMap.put(mi.pid, mi);
   1614                         }
   1615                         updateCpuStatsNow();
   1616                         synchronized (mProcessCpuTracker) {
   1617                             final int N = mProcessCpuTracker.countStats();
   1618                             for (int i=0; i<N; i++) {
   1619                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   1620                                 if (st.vsize > 0) {
   1621                                     long pss = Debug.getPss(st.pid, null);
   1622                                     if (pss > 0) {
   1623                                         if (infoMap.indexOfKey(st.pid) < 0) {
   1624                                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   1625                                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   1626                                             mi.pss = pss;
   1627                                             memInfos.add(mi);
   1628                                         }
   1629                                     }
   1630                                 }
   1631                             }
   1632                         }
   1633 
   1634                         long totalPss = 0;
   1635                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1636                             ProcessMemInfo mi = memInfos.get(i);
   1637                             if (mi.pss == 0) {
   1638                                 mi.pss = Debug.getPss(mi.pid, null);
   1639                             }
   1640                             totalPss += mi.pss;
   1641                         }
   1642                         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   1643                             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   1644                                 if (lhs.oomAdj != rhs.oomAdj) {
   1645                                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   1646                                 }
   1647                                 if (lhs.pss != rhs.pss) {
   1648                                     return lhs.pss < rhs.pss ? 1 : -1;
   1649                                 }
   1650                                 return 0;
   1651                             }
   1652                         });
   1653 
   1654                         StringBuilder tag = new StringBuilder(128);
   1655                         StringBuilder stack = new StringBuilder(128);
   1656                         tag.append("Low on memory -- ");
   1657                         appendMemBucket(tag, totalPss, "total", false);
   1658                         appendMemBucket(stack, totalPss, "total", true);
   1659 
   1660                         StringBuilder logBuilder = new StringBuilder(1024);
   1661                         logBuilder.append("Low on memory:\n");
   1662 
   1663                         boolean firstLine = true;
   1664                         int lastOomAdj = Integer.MIN_VALUE;
   1665                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1666                             ProcessMemInfo mi = memInfos.get(i);
   1667 
   1668                             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   1669                                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   1670                                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   1671                                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   1672                                 if (lastOomAdj != mi.oomAdj) {
   1673                                     lastOomAdj = mi.oomAdj;
   1674                                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1675                                         tag.append(" / ");
   1676                                     }
   1677                                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   1678                                         if (firstLine) {
   1679                                             stack.append(":");
   1680                                             firstLine = false;
   1681                                         }
   1682                                         stack.append("\n\t at ");
   1683                                     } else {
   1684                                         stack.append("$");
   1685                                     }
   1686                                 } else {
   1687                                     tag.append(" ");
   1688                                     stack.append("$");
   1689                                 }
   1690                                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1691                                     appendMemBucket(tag, mi.pss, mi.name, false);
   1692                                 }
   1693                                 appendMemBucket(stack, mi.pss, mi.name, true);
   1694                                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   1695                                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   1696                                     stack.append("(");
   1697                                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   1698                                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   1699                                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   1700                                             stack.append(":");
   1701                                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   1702                                         }
   1703                                     }
   1704                                     stack.append(")");
   1705                                 }
   1706                             }
   1707 
   1708                             logBuilder.append("  ");
   1709                             logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
   1710                             logBuilder.append(' ');
   1711                             logBuilder.append(ProcessList.makeProcStateString(mi.procState));
   1712                             logBuilder.append(' ');
   1713                             ProcessList.appendRamKb(logBuilder, mi.pss);
   1714                             logBuilder.append(" kB: ");
   1715                             logBuilder.append(mi.name);
   1716                             logBuilder.append(" (");
   1717                             logBuilder.append(mi.pid);
   1718                             logBuilder.append(") ");
   1719                             logBuilder.append(mi.adjType);
   1720                             logBuilder.append('\n');
   1721                             if (mi.adjReason != null) {
   1722                                 logBuilder.append("                      ");
   1723                                 logBuilder.append(mi.adjReason);
   1724                                 logBuilder.append('\n');
   1725                             }
   1726                         }
   1727 
   1728                         logBuilder.append("           ");
   1729                         ProcessList.appendRamKb(logBuilder, totalPss);
   1730                         logBuilder.append(" kB: TOTAL\n");
   1731 
   1732                         long[] infos = new long[Debug.MEMINFO_COUNT];
   1733                         Debug.getMemInfo(infos);
   1734                         logBuilder.append("  MemInfo: ");
   1735                         logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
   1736                         logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
   1737                         logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
   1738                         logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
   1739                         logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
   1740                         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   1741                             logBuilder.append("  ZRAM: ");
   1742                             logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
   1743                             logBuilder.append(" kB RAM, ");
   1744                             logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
   1745                             logBuilder.append(" kB swap total, ");
   1746                             logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
   1747                             logBuilder.append(" kB swap free\n");
   1748                         }
   1749                         Slog.i(TAG, logBuilder.toString());
   1750 
   1751                         StringBuilder dropBuilder = new StringBuilder(1024);
   1752                         /*
   1753                         StringWriter oomSw = new StringWriter();
   1754                         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   1755                         StringWriter catSw = new StringWriter();
   1756                         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1757                         String[] emptyArgs = new String[] { };
   1758                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   1759                         oomPw.flush();
   1760                         String oomString = oomSw.toString();
   1761                         */
   1762                         dropBuilder.append(stack);
   1763                         dropBuilder.append('\n');
   1764                         dropBuilder.append('\n');
   1765                         dropBuilder.append(logBuilder);
   1766                         dropBuilder.append('\n');
   1767                         /*
   1768                         dropBuilder.append(oomString);
   1769                         dropBuilder.append('\n');
   1770                         */
   1771                         StringWriter catSw = new StringWriter();
   1772                         synchronized (ActivityManagerService.this) {
   1773                             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1774                             String[] emptyArgs = new String[] { };
   1775                             catPw.println();
   1776                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1777                             catPw.println();
   1778                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   1779                                     false, false, null);
   1780                             catPw.println();
   1781                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1782                             catPw.flush();
   1783                         }
   1784                         dropBuilder.append(catSw.toString());
   1785                         addErrorToDropBox("lowmem", null, "system_server", null,
   1786                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1787                         //Slog.i(TAG, "Sent to dropbox:");
   1788                         //Slog.i(TAG, dropBuilder.toString());
   1789                         synchronized (ActivityManagerService.this) {
   1790                             long now = SystemClock.uptimeMillis();
   1791                             if (mLastMemUsageReportTime < now) {
   1792                                 mLastMemUsageReportTime = now;
   1793                             }
   1794                         }
   1795                     }
   1796                 };
   1797                 thread.start();
   1798                 break;
   1799             }
   1800             case START_USER_SWITCH_MSG: {
   1801                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
   1802                 break;
   1803             }
   1804             case REPORT_USER_SWITCH_MSG: {
   1805                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1806                 break;
   1807             }
   1808             case CONTINUE_USER_SWITCH_MSG: {
   1809                 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1810                 break;
   1811             }
   1812             case USER_SWITCH_TIMEOUT_MSG: {
   1813                 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
   1814                 break;
   1815             }
   1816             case IMMERSIVE_MODE_LOCK_MSG: {
   1817                 final boolean nextState = (msg.arg1 != 0);
   1818                 if (mUpdateLock.isHeld() != nextState) {
   1819                     if (DEBUG_IMMERSIVE) {
   1820                         final ActivityRecord r = (ActivityRecord) msg.obj;
   1821                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
   1822                     }
   1823                     if (nextState) {
   1824                         mUpdateLock.acquire();
   1825                     } else {
   1826                         mUpdateLock.release();
   1827                     }
   1828                 }
   1829                 break;
   1830             }
   1831             case PERSIST_URI_GRANTS_MSG: {
   1832                 writeGrantedUriPermissions();
   1833                 break;
   1834             }
   1835             case REQUEST_ALL_PSS_MSG: {
   1836                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1837                 break;
   1838             }
   1839             case START_PROFILES_MSG: {
   1840                 synchronized (ActivityManagerService.this) {
   1841                     startProfilesLocked();
   1842                 }
   1843                 break;
   1844             }
   1845             case UPDATE_TIME: {
   1846                 synchronized (ActivityManagerService.this) {
   1847                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1848                         ProcessRecord r = mLruProcesses.get(i);
   1849                         if (r.thread != null) {
   1850                             try {
   1851                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
   1852                             } catch (RemoteException ex) {
   1853                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
   1854                             }
   1855                         }
   1856                     }
   1857                 }
   1858                 break;
   1859             }
   1860             case SYSTEM_USER_START_MSG: {
   1861                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   1862                         Integer.toString(msg.arg1), msg.arg1);
   1863                 mSystemServiceManager.startUser(msg.arg1);
   1864                 break;
   1865             }
   1866             case SYSTEM_USER_CURRENT_MSG: {
   1867                 mBatteryStatsService.noteEvent(
   1868                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
   1869                         Integer.toString(msg.arg2), msg.arg2);
   1870                 mBatteryStatsService.noteEvent(
   1871                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   1872                         Integer.toString(msg.arg1), msg.arg1);
   1873                 mSystemServiceManager.switchUser(msg.arg1);
   1874                 mLockToAppRequest.clearPrompt();
   1875                 break;
   1876             }
   1877             case ENTER_ANIMATION_COMPLETE_MSG: {
   1878                 synchronized (ActivityManagerService.this) {
   1879                     ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
   1880                     if (r != null && r.app != null && r.app.thread != null) {
   1881                         try {
   1882                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
   1883                         } catch (RemoteException e) {
   1884                         }
   1885                     }
   1886                 }
   1887                 break;
   1888             }
   1889             case FINISH_BOOTING_MSG: {
   1890                 if (msg.arg1 != 0) {
   1891                     finishBooting();
   1892                 }
   1893                 if (msg.arg2 != 0) {
   1894                     enableScreenAfterBoot();
   1895                 }
   1896                 break;
   1897             }
   1898             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
   1899                 try {
   1900                     Locale l = (Locale) msg.obj;
   1901                     IBinder service = ServiceManager.getService("mount");
   1902                     IMountService mountService = IMountService.Stub.asInterface(service);
   1903                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
   1904                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
   1905                 } catch (RemoteException e) {
   1906                     Log.e(TAG, "Error storing locale for decryption UI", e);
   1907                 }
   1908                 break;
   1909             }
   1910             }
   1911         }
   1912     };
   1913 
   1914     static final int COLLECT_PSS_BG_MSG = 1;
   1915 
   1916     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   1917         @Override
   1918         public void handleMessage(Message msg) {
   1919             switch (msg.what) {
   1920             case COLLECT_PSS_BG_MSG: {
   1921                 long start = SystemClock.uptimeMillis();
   1922                 MemInfoReader memInfo = null;
   1923                 synchronized (ActivityManagerService.this) {
   1924                     if (mFullPssPending) {
   1925                         mFullPssPending = false;
   1926                         memInfo = new MemInfoReader();
   1927                     }
   1928                 }
   1929                 if (memInfo != null) {
   1930                     updateCpuStatsNow();
   1931                     long nativeTotalPss = 0;
   1932                     synchronized (mProcessCpuTracker) {
   1933                         final int N = mProcessCpuTracker.countStats();
   1934                         for (int j=0; j<N; j++) {
   1935                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
   1936                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
   1937                                 // This is definitely an application process; skip it.
   1938                                 continue;
   1939                             }
   1940                             synchronized (mPidsSelfLocked) {
   1941                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
   1942                                     // This is one of our own processes; skip it.
   1943                                     continue;
   1944                                 }
   1945                             }
   1946                             nativeTotalPss += Debug.getPss(st.pid, null);
   1947                         }
   1948                     }
   1949                     memInfo.readMemInfo();
   1950                     synchronized (ActivityManagerService.this) {
   1951                         if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
   1952                                 + (SystemClock.uptimeMillis()-start) + "ms");
   1953                         mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
   1954                                 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
   1955                                 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
   1956                                         +memInfo.getSlabSizeKb(),
   1957                                 nativeTotalPss);
   1958                     }
   1959                 }
   1960 
   1961                 int i=0, num=0;
   1962                 long[] tmp = new long[1];
   1963                 do {
   1964                     ProcessRecord proc;
   1965                     int procState;
   1966                     int pid;
   1967                     synchronized (ActivityManagerService.this) {
   1968                         if (i >= mPendingPssProcesses.size()) {
   1969                             if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
   1970                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
   1971                             mPendingPssProcesses.clear();
   1972                             return;
   1973                         }
   1974                         proc = mPendingPssProcesses.get(i);
   1975                         procState = proc.pssProcState;
   1976                         if (proc.thread != null && procState == proc.setProcState) {
   1977                             pid = proc.pid;
   1978                         } else {
   1979                             proc = null;
   1980                             pid = 0;
   1981                         }
   1982                         i++;
   1983                     }
   1984                     if (proc != null) {
   1985                         long pss = Debug.getPss(pid, tmp);
   1986                         synchronized (ActivityManagerService.this) {
   1987                             if (proc.thread != null && proc.setProcState == procState
   1988                                     && proc.pid == pid) {
   1989                                 num++;
   1990                                 proc.lastPssTime = SystemClock.uptimeMillis();
   1991                                 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
   1992                                 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
   1993                                         + ": " + pss + " lastPss=" + proc.lastPss
   1994                                         + " state=" + ProcessList.makeProcStateString(procState));
   1995                                 if (proc.initialIdlePss == 0) {
   1996                                     proc.initialIdlePss = pss;
   1997                                 }
   1998                                 proc.lastPss = pss;
   1999                                 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   2000                                     proc.lastCachedPss = pss;
   2001                                 }
   2002                             }
   2003                         }
   2004                     }
   2005                 } while (true);
   2006             }
   2007             }
   2008         }
   2009     };
   2010 
   2011     /**
   2012      * Monitor for package changes and update our internal state.
   2013      */
   2014     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
   2015         @Override
   2016         public void onPackageRemoved(String packageName, int uid) {
   2017             // Remove all tasks with activities in the specified package from the list of recent tasks
   2018             final int eventUserId = getChangingUserId();
   2019             synchronized (ActivityManagerService.this) {
   2020                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   2021                     TaskRecord tr = mRecentTasks.get(i);
   2022                     if (tr.userId != eventUserId) continue;
   2023 
   2024                     ComponentName cn = tr.intent.getComponent();
   2025                     if (cn != null && cn.getPackageName().equals(packageName)) {
   2026                         // If the package name matches, remove the task and kill the process
   2027                         removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
   2028                     }
   2029                 }
   2030             }
   2031         }
   2032 
   2033         @Override
   2034         public boolean onPackageChanged(String packageName, int uid, String[] components) {
   2035             onPackageModified(packageName);
   2036             return true;
   2037         }
   2038 
   2039         @Override
   2040         public void onPackageModified(String packageName) {
   2041             final int eventUserId = getChangingUserId();
   2042             final IPackageManager pm = AppGlobals.getPackageManager();
   2043             final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
   2044                     new ArrayList<Pair<Intent, Integer>>();
   2045             final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
   2046             final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
   2047             // Copy the list of recent tasks so that we don't hold onto the lock on
   2048             // ActivityManagerService for long periods while checking if components exist.
   2049             synchronized (ActivityManagerService.this) {
   2050                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   2051                     TaskRecord tr = mRecentTasks.get(i);
   2052                     if (tr.userId != eventUserId) continue;
   2053 
   2054                     recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
   2055                 }
   2056             }
   2057             // Check the recent tasks and filter out all tasks with components that no longer exist.
   2058             for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
   2059                 Pair<Intent, Integer> p = recentTaskIntents.get(i);
   2060                 ComponentName cn = p.first.getComponent();
   2061                 if (cn != null && cn.getPackageName().equals(packageName)) {
   2062                     if (componentsKnownToExist.contains(cn)) {
   2063                         // If we know that the component still exists in the package, then skip
   2064                         continue;
   2065                     }
   2066                     try {
   2067                         ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
   2068                         if (info != null) {
   2069                             componentsKnownToExist.add(cn);
   2070                         } else {
   2071                             tasksToRemove.add(p.second);
   2072                         }
   2073                     } catch (RemoteException e) {
   2074                         Log.e(TAG, "Failed to query activity info for component: " + cn, e);
   2075                     }
   2076                 }
   2077             }
   2078             // Prune all the tasks with removed components from the list of recent tasks
   2079             synchronized (ActivityManagerService.this) {
   2080                 for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
   2081                     // Remove the task but don't kill the process (since other components in that
   2082                     // package may still be running and in the background)
   2083                     removeTaskByIdLocked(tasksToRemove.get(i), 0);
   2084                 }
   2085             }
   2086         }
   2087 
   2088         @Override
   2089         public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
   2090             // Force stop the specified packages
   2091             int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
   2092             if (packages != null) {
   2093                 for (String pkg : packages) {
   2094                     synchronized (ActivityManagerService.this) {
   2095                         if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
   2096                                 userId, "finished booting")) {
   2097                             return true;
   2098                         }
   2099                     }
   2100                 }
   2101             }
   2102             return false;
   2103         }
   2104     };
   2105 
   2106     public void setSystemProcess() {
   2107         try {
   2108             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   2109             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
   2110             ServiceManager.addService("meminfo", new MemBinder(this));
   2111             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
   2112             ServiceManager.addService("dbinfo", new DbBinder(this));
   2113             if (MONITOR_CPU_USAGE) {
   2114                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
   2115             }
   2116             ServiceManager.addService("permission", new PermissionController(this));
   2117 
   2118             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
   2119                     "android", STOCK_PM_FLAGS);
   2120             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
   2121 
   2122             synchronized (this) {
   2123                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
   2124                 app.persistent = true;
   2125                 app.pid = MY_PID;
   2126                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   2127                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
   2128                 mProcessNames.put(app.processName, app.uid, app);
   2129                 synchronized (mPidsSelfLocked) {
   2130                     mPidsSelfLocked.put(app.pid, app);
   2131                 }
   2132                 updateLruProcessLocked(app, false, null);
   2133                 updateOomAdjLocked();
   2134             }
   2135         } catch (PackageManager.NameNotFoundException e) {
   2136             throw new RuntimeException(
   2137                     "Unable to find android system package", e);
   2138         }
   2139     }
   2140 
   2141     public void setWindowManager(WindowManagerService wm) {
   2142         mWindowManager = wm;
   2143         mStackSupervisor.setWindowManager(wm);
   2144     }
   2145 
   2146     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
   2147         mUsageStatsService = usageStatsManager;
   2148     }
   2149 
   2150     public void startObservingNativeCrashes() {
   2151         final NativeCrashListener ncl = new NativeCrashListener(this);
   2152         ncl.start();
   2153     }
   2154 
   2155     public IAppOpsService getAppOpsService() {
   2156         return mAppOpsService;
   2157     }
   2158 
   2159     static class MemBinder extends Binder {
   2160         ActivityManagerService mActivityManagerService;
   2161         MemBinder(ActivityManagerService activityManagerService) {
   2162             mActivityManagerService = activityManagerService;
   2163         }
   2164 
   2165         @Override
   2166         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2167             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2168                     != PackageManager.PERMISSION_GRANTED) {
   2169                 pw.println("Permission Denial: can't dump meminfo from from pid="
   2170                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2171                         + " without permission " + android.Manifest.permission.DUMP);
   2172                 return;
   2173             }
   2174 
   2175             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   2176         }
   2177     }
   2178 
   2179     static class GraphicsBinder extends Binder {
   2180         ActivityManagerService mActivityManagerService;
   2181         GraphicsBinder(ActivityManagerService activityManagerService) {
   2182             mActivityManagerService = activityManagerService;
   2183         }
   2184 
   2185         @Override
   2186         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2187             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2188                     != PackageManager.PERMISSION_GRANTED) {
   2189                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   2190                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2191                         + " without permission " + android.Manifest.permission.DUMP);
   2192                 return;
   2193             }
   2194 
   2195             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   2196         }
   2197     }
   2198 
   2199     static class DbBinder extends Binder {
   2200         ActivityManagerService mActivityManagerService;
   2201         DbBinder(ActivityManagerService activityManagerService) {
   2202             mActivityManagerService = activityManagerService;
   2203         }
   2204 
   2205         @Override
   2206         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2207             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2208                     != PackageManager.PERMISSION_GRANTED) {
   2209                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   2210                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2211                         + " without permission " + android.Manifest.permission.DUMP);
   2212                 return;
   2213             }
   2214 
   2215             mActivityManagerService.dumpDbInfo(fd, pw, args);
   2216         }
   2217     }
   2218 
   2219     static class CpuBinder extends Binder {
   2220         ActivityManagerService mActivityManagerService;
   2221         CpuBinder(ActivityManagerService activityManagerService) {
   2222             mActivityManagerService = activityManagerService;
   2223         }
   2224 
   2225         @Override
   2226         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2227             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   2228                     != PackageManager.PERMISSION_GRANTED) {
   2229                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   2230                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   2231                         + " without permission " + android.Manifest.permission.DUMP);
   2232                 return;
   2233             }
   2234 
   2235             synchronized (mActivityManagerService.mProcessCpuTracker) {
   2236                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   2237                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   2238                         SystemClock.uptimeMillis()));
   2239             }
   2240         }
   2241     }
   2242 
   2243     public static final class Lifecycle extends SystemService {
   2244         private final ActivityManagerService mService;
   2245 
   2246         public Lifecycle(Context context) {
   2247             super(context);
   2248             mService = new ActivityManagerService(context);
   2249         }
   2250 
   2251         @Override
   2252         public void onStart() {
   2253             mService.start();
   2254         }
   2255 
   2256         public ActivityManagerService getService() {
   2257             return mService;
   2258         }
   2259     }
   2260 
   2261     // Note: This method is invoked on the main thread but may need to attach various
   2262     // handlers to other threads.  So take care to be explicit about the looper.
   2263     public ActivityManagerService(Context systemContext) {
   2264         mContext = systemContext;
   2265         mFactoryTest = FactoryTest.getMode();
   2266         mSystemThread = ActivityThread.currentActivityThread();
   2267 
   2268         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   2269 
   2270         mHandlerThread = new ServiceThread(TAG,
   2271                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
   2272         mHandlerThread.start();
   2273         mHandler = new MainHandler(mHandlerThread.getLooper());
   2274 
   2275         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2276                 "foreground", BROADCAST_FG_TIMEOUT, false);
   2277         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
   2278                 "background", BROADCAST_BG_TIMEOUT, true);
   2279         mBroadcastQueues[0] = mFgBroadcastQueue;
   2280         mBroadcastQueues[1] = mBgBroadcastQueue;
   2281 
   2282         mServices = new ActiveServices(this);
   2283         mProviderMap = new ProviderMap(this);
   2284 
   2285         // TODO: Move creation of battery stats service outside of activity manager service.
   2286         File dataDir = Environment.getDataDirectory();
   2287         File systemDir = new File(dataDir, "system");
   2288         systemDir.mkdirs();
   2289         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
   2290         mBatteryStatsService.getActiveStatistics().readLocked();
   2291         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2292         mOnBattery = DEBUG_POWER ? true
   2293                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   2294         mBatteryStatsService.getActiveStatistics().setCallback(this);
   2295 
   2296         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   2297 
   2298         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
   2299 
   2300         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   2301 
   2302         // User 0 is the first and only user that runs at boot.
   2303         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   2304         mUserLru.add(Integer.valueOf(0));
   2305         updateStartedUserArrayLocked();
   2306 
   2307         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   2308             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   2309 
   2310         mConfiguration.setToDefaults();
   2311         mConfiguration.setLocale(Locale.getDefault());
   2312 
   2313         mConfigurationSeq = mConfiguration.seq = 1;
   2314         mProcessCpuTracker.init();
   2315 
   2316         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
   2317         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
   2318         mStackSupervisor = new ActivityStackSupervisor(this);
   2319         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
   2320 
   2321         mProcessCpuThread = new Thread("CpuTracker") {
   2322             @Override
   2323             public void run() {
   2324                 while (true) {
   2325                     try {
   2326                         try {
   2327                             synchronized(this) {
   2328                                 final long now = SystemClock.uptimeMillis();
   2329                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2330                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2331                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2332                                 //        + ", write delay=" + nextWriteDelay);
   2333                                 if (nextWriteDelay < nextCpuDelay) {
   2334                                     nextCpuDelay = nextWriteDelay;
   2335                                 }
   2336                                 if (nextCpuDelay > 0) {
   2337                                     mProcessCpuMutexFree.set(true);
   2338                                     this.wait(nextCpuDelay);
   2339                                 }
   2340                             }
   2341                         } catch (InterruptedException e) {
   2342                         }
   2343                         updateCpuStatsNow();
   2344                     } catch (Exception e) {
   2345                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2346                     }
   2347                 }
   2348             }
   2349         };
   2350 
   2351         mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
   2352 
   2353         Watchdog.getInstance().addMonitor(this);
   2354         Watchdog.getInstance().addThread(mHandler);
   2355     }
   2356 
   2357     public void setSystemServiceManager(SystemServiceManager mgr) {
   2358         mSystemServiceManager = mgr;
   2359     }
   2360 
   2361     private void start() {
   2362         Process.removeAllProcessGroups();
   2363         mProcessCpuThread.start();
   2364 
   2365         mBatteryStatsService.publish(mContext);
   2366         mAppOpsService.publish(mContext);
   2367         Slog.d("AppOps", "AppOpsService published");
   2368         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   2369     }
   2370 
   2371     public void initPowerManagement() {
   2372         mStackSupervisor.initPowerManagement();
   2373         mBatteryStatsService.initPowerManagement();
   2374     }
   2375 
   2376     @Override
   2377     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2378             throws RemoteException {
   2379         if (code == SYSPROPS_TRANSACTION) {
   2380             // We need to tell all apps about the system property change.
   2381             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2382             synchronized(this) {
   2383                 final int NP = mProcessNames.getMap().size();
   2384                 for (int ip=0; ip<NP; ip++) {
   2385                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2386                     final int NA = apps.size();
   2387                     for (int ia=0; ia<NA; ia++) {
   2388                         ProcessRecord app = apps.valueAt(ia);
   2389                         if (app.thread != null) {
   2390                             procs.add(app.thread.asBinder());
   2391                         }
   2392                     }
   2393                 }
   2394             }
   2395 
   2396             int N = procs.size();
   2397             for (int i=0; i<N; i++) {
   2398                 Parcel data2 = Parcel.obtain();
   2399                 try {
   2400                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2401                 } catch (RemoteException e) {
   2402                 }
   2403                 data2.recycle();
   2404             }
   2405         }
   2406         try {
   2407             return super.onTransact(code, data, reply, flags);
   2408         } catch (RuntimeException e) {
   2409             // The activity manager only throws security exceptions, so let's
   2410             // log all others.
   2411             if (!(e instanceof SecurityException)) {
   2412                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2413             }
   2414             throw e;
   2415         }
   2416     }
   2417 
   2418     void updateCpuStats() {
   2419         final long now = SystemClock.uptimeMillis();
   2420         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2421             return;
   2422         }
   2423         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2424             synchronized (mProcessCpuThread) {
   2425                 mProcessCpuThread.notify();
   2426             }
   2427         }
   2428     }
   2429 
   2430     void updateCpuStatsNow() {
   2431         synchronized (mProcessCpuTracker) {
   2432             mProcessCpuMutexFree.set(false);
   2433             final long now = SystemClock.uptimeMillis();
   2434             boolean haveNewCpuStats = false;
   2435 
   2436             if (MONITOR_CPU_USAGE &&
   2437                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2438                 mLastCpuTime.set(now);
   2439                 haveNewCpuStats = true;
   2440                 mProcessCpuTracker.update();
   2441                 //Slog.i(TAG, mProcessCpu.printCurrentState());
   2442                 //Slog.i(TAG, "Total CPU usage: "
   2443                 //        + mProcessCpu.getTotalCpuPercent() + "%");
   2444 
   2445                 // Slog the cpu usage if the property is set.
   2446                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   2447                     int user = mProcessCpuTracker.getLastUserTime();
   2448                     int system = mProcessCpuTracker.getLastSystemTime();
   2449                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2450                     int irq = mProcessCpuTracker.getLastIrqTime();
   2451                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2452                     int idle = mProcessCpuTracker.getLastIdleTime();
   2453 
   2454                     int total = user + system + iowait + irq + softIrq + idle;
   2455                     if (total == 0) total = 1;
   2456 
   2457                     EventLog.writeEvent(EventLogTags.CPU,
   2458                             ((user+system+iowait+irq+softIrq) * 100) / total,
   2459                             (user * 100) / total,
   2460                             (system * 100) / total,
   2461                             (iowait * 100) / total,
   2462                             (irq * 100) / total,
   2463                             (softIrq * 100) / total);
   2464                 }
   2465             }
   2466 
   2467             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
   2468             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2469             synchronized(bstats) {
   2470                 synchronized(mPidsSelfLocked) {
   2471                     if (haveNewCpuStats) {
   2472                         if (mOnBattery) {
   2473                             int perc = bstats.startAddingCpuLocked();
   2474                             int totalUTime = 0;
   2475                             int totalSTime = 0;
   2476                             final int N = mProcessCpuTracker.countStats();
   2477                             for (int i=0; i<N; i++) {
   2478                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2479                                 if (!st.working) {
   2480                                     continue;
   2481                                 }
   2482                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2483                                 int otherUTime = (st.rel_utime*perc)/100;
   2484                                 int otherSTime = (st.rel_stime*perc)/100;
   2485                                 totalUTime += otherUTime;
   2486                                 totalSTime += otherSTime;
   2487                                 if (pr != null) {
   2488                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
   2489                                     if (ps == null || !ps.isActive()) {
   2490                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
   2491                                                 pr.info.uid, pr.processName);
   2492                                     }
   2493                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2494                                             st.rel_stime-otherSTime);
   2495                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2496                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   2497                                 } else {
   2498                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2499                                     if (ps == null || !ps.isActive()) {
   2500                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
   2501                                                 bstats.mapUid(st.uid), st.name);
   2502                                     }
   2503                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2504                                             st.rel_stime-otherSTime);
   2505                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2506                                 }
   2507                             }
   2508                             bstats.finishAddingCpuLocked(perc, totalUTime,
   2509                                     totalSTime, cpuSpeedTimes);
   2510                         }
   2511                     }
   2512                 }
   2513 
   2514                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2515                     mLastWriteTime = now;
   2516                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2517                 }
   2518             }
   2519         }
   2520     }
   2521 
   2522     @Override
   2523     public void batteryNeedsCpuUpdate() {
   2524         updateCpuStatsNow();
   2525     }
   2526 
   2527     @Override
   2528     public void batteryPowerChanged(boolean onBattery) {
   2529         // When plugging in, update the CPU stats first before changing
   2530         // the plug state.
   2531         updateCpuStatsNow();
   2532         synchronized (this) {
   2533             synchronized(mPidsSelfLocked) {
   2534                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2535             }
   2536         }
   2537     }
   2538 
   2539     /**
   2540      * Initialize the application bind args. These are passed to each
   2541      * process when the bindApplication() IPC is sent to the process. They're
   2542      * lazily setup to make sure the services are running when they're asked for.
   2543      */
   2544     private HashMap<String, IBinder> getCommonServicesLocked() {
   2545         if (mAppBindArgs == null) {
   2546             mAppBindArgs = new HashMap<String, IBinder>();
   2547 
   2548             // Setup the application init args
   2549             mAppBindArgs.put("package", ServiceManager.getService("package"));
   2550             mAppBindArgs.put("window", ServiceManager.getService("window"));
   2551             mAppBindArgs.put(Context.ALARM_SERVICE,
   2552                     ServiceManager.getService(Context.ALARM_SERVICE));
   2553         }
   2554         return mAppBindArgs;
   2555     }
   2556 
   2557     final void setFocusedActivityLocked(ActivityRecord r) {
   2558         if (mFocusedActivity != r) {
   2559             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
   2560             mFocusedActivity = r;
   2561             if (r.task != null && r.task.voiceInteractor != null) {
   2562                 startRunningVoiceLocked();
   2563             } else {
   2564                 finishRunningVoiceLocked();
   2565             }
   2566             mStackSupervisor.setFocusedStack(r);
   2567             if (r != null) {
   2568                 mWindowManager.setFocusedApp(r.appToken, true);
   2569             }
   2570             applyUpdateLockStateLocked(r);
   2571         }
   2572     }
   2573 
   2574     final void clearFocusedActivity(ActivityRecord r) {
   2575         if (mFocusedActivity == r) {
   2576             mFocusedActivity = null;
   2577         }
   2578     }
   2579 
   2580     @Override
   2581     public void setFocusedStack(int stackId) {
   2582         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
   2583         synchronized (ActivityManagerService.this) {
   2584             ActivityStack stack = mStackSupervisor.getStack(stackId);
   2585             if (stack != null) {
   2586                 ActivityRecord r = stack.topRunningActivityLocked(null);
   2587                 if (r != null) {
   2588                     setFocusedActivityLocked(r);
   2589                 }
   2590             }
   2591         }
   2592     }
   2593 
   2594     @Override
   2595     public void notifyActivityDrawn(IBinder token) {
   2596         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
   2597         synchronized (this) {
   2598             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
   2599             if (r != null) {
   2600                 r.task.stack.notifyActivityDrawnLocked(r);
   2601             }
   2602         }
   2603     }
   2604 
   2605     final void applyUpdateLockStateLocked(ActivityRecord r) {
   2606         // Modifications to the UpdateLock state are done on our handler, outside
   2607         // the activity manager's locks.  The new state is determined based on the
   2608         // state *now* of the relevant activity record.  The object is passed to
   2609         // the handler solely for logging detail, not to be consulted/modified.
   2610         final boolean nextState = r != null && r.immersive;
   2611         mHandler.sendMessage(
   2612                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   2613     }
   2614 
   2615     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   2616         Message msg = Message.obtain();
   2617         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
   2618         msg.obj = r.task.askedCompatMode ? null : r;
   2619         mHandler.sendMessage(msg);
   2620     }
   2621 
   2622     private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   2623             String what, Object obj, ProcessRecord srcApp) {
   2624         app.lastActivityTime = now;
   2625 
   2626         if (app.activities.size() > 0) {
   2627             // Don't want to touch dependent processes that are hosting activities.
   2628             return index;
   2629         }
   2630 
   2631         int lrui = mLruProcesses.lastIndexOf(app);
   2632         if (lrui < 0) {
   2633             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   2634                     + what + " " + obj + " from " + srcApp);
   2635             return index;
   2636         }
   2637 
   2638         if (lrui >= index) {
   2639             // Don't want to cause this to move dependent processes *back* in the
   2640             // list as if they were less frequently used.
   2641             return index;
   2642         }
   2643 
   2644         if (lrui >= mLruProcessActivityStart) {
   2645             // Don't want to touch dependent processes that are hosting activities.
   2646             return index;
   2647         }
   2648 
   2649         mLruProcesses.remove(lrui);
   2650         if (index > 0) {
   2651             index--;
   2652         }
   2653         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
   2654                 + " in LRU list: " + app);
   2655         mLruProcesses.add(index, app);
   2656         return index;
   2657     }
   2658 
   2659     final void removeLruProcessLocked(ProcessRecord app) {
   2660         int lrui = mLruProcesses.lastIndexOf(app);
   2661         if (lrui >= 0) {
   2662             if (!app.killed) {
   2663                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
   2664                 Process.killProcessQuiet(app.pid);
   2665                 Process.killProcessGroup(app.info.uid, app.pid);
   2666             }
   2667             if (lrui <= mLruProcessActivityStart) {
   2668                 mLruProcessActivityStart--;
   2669             }
   2670             if (lrui <= mLruProcessServiceStart) {
   2671                 mLruProcessServiceStart--;
   2672             }
   2673             mLruProcesses.remove(lrui);
   2674         }
   2675     }
   2676 
   2677     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   2678             ProcessRecord client) {
   2679         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
   2680                 || app.treatLikeActivity;
   2681         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   2682         if (!activityChange && hasActivity) {
   2683             // The process has activities, so we are only allowing activity-based adjustments
   2684             // to move it.  It should be kept in the front of the list with other
   2685             // processes that have activities, and we don't want those to change their
   2686             // order except due to activity operations.
   2687             return;
   2688         }
   2689 
   2690         mLruSeq++;
   2691         final long now = SystemClock.uptimeMillis();
   2692         app.lastActivityTime = now;
   2693 
   2694         // First a quick reject: if the app is already at the position we will
   2695         // put it, then there is nothing to do.
   2696         if (hasActivity) {
   2697             final int N = mLruProcesses.size();
   2698             if (N > 0 && mLruProcesses.get(N-1) == app) {
   2699                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
   2700                 return;
   2701             }
   2702         } else {
   2703             if (mLruProcessServiceStart > 0
   2704                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   2705                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
   2706                 return;
   2707             }
   2708         }
   2709 
   2710         int lrui = mLruProcesses.lastIndexOf(app);
   2711 
   2712         if (app.persistent && lrui >= 0) {
   2713             // We don't care about the position of persistent processes, as long as
   2714             // they are in the list.
   2715             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
   2716             return;
   2717         }
   2718 
   2719         /* In progress: compute new position first, so we can avoid doing work
   2720            if the process is not actually going to move.  Not yet working.
   2721         int addIndex;
   2722         int nextIndex;
   2723         boolean inActivity = false, inService = false;
   2724         if (hasActivity) {
   2725             // Process has activities, put it at the very tipsy-top.
   2726             addIndex = mLruProcesses.size();
   2727             nextIndex = mLruProcessServiceStart;
   2728             inActivity = true;
   2729         } else if (hasService) {
   2730             // Process has services, put it at the top of the service list.
   2731             addIndex = mLruProcessActivityStart;
   2732             nextIndex = mLruProcessServiceStart;
   2733             inActivity = true;
   2734             inService = true;
   2735         } else  {
   2736             // Process not otherwise of interest, it goes to the top of the non-service area.
   2737             addIndex = mLruProcessServiceStart;
   2738             if (client != null) {
   2739                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2740                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   2741                         + app);
   2742                 if (clientIndex >= 0 && addIndex > clientIndex) {
   2743                     addIndex = clientIndex;
   2744                 }
   2745             }
   2746             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   2747         }
   2748 
   2749         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   2750                 + mLruProcessActivityStart + "): " + app);
   2751         */
   2752 
   2753         if (lrui >= 0) {
   2754             if (lrui < mLruProcessActivityStart) {
   2755                 mLruProcessActivityStart--;
   2756             }
   2757             if (lrui < mLruProcessServiceStart) {
   2758                 mLruProcessServiceStart--;
   2759             }
   2760             /*
   2761             if (addIndex > lrui) {
   2762                 addIndex--;
   2763             }
   2764             if (nextIndex > lrui) {
   2765                 nextIndex--;
   2766             }
   2767             */
   2768             mLruProcesses.remove(lrui);
   2769         }
   2770 
   2771         /*
   2772         mLruProcesses.add(addIndex, app);
   2773         if (inActivity) {
   2774             mLruProcessActivityStart++;
   2775         }
   2776         if (inService) {
   2777             mLruProcessActivityStart++;
   2778         }
   2779         */
   2780 
   2781         int nextIndex;
   2782         if (hasActivity) {
   2783             final int N = mLruProcesses.size();
   2784             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
   2785                 // Process doesn't have activities, but has clients with
   2786                 // activities...  move it up, but one below the top (the top
   2787                 // should always have a real activity).
   2788                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
   2789                 mLruProcesses.add(N-1, app);
   2790                 // To keep it from spamming the LRU list (by making a bunch of clients),
   2791                 // we will push down any other entries owned by the app.
   2792                 final int uid = app.info.uid;
   2793                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
   2794                     ProcessRecord subProc = mLruProcesses.get(i);
   2795                     if (subProc.info.uid == uid) {
   2796                         // We want to push this one down the list.  If the process after
   2797                         // it is for the same uid, however, don't do so, because we don't
   2798                         // want them internally to be re-ordered.
   2799                         if (mLruProcesses.get(i-1).info.uid != uid) {
   2800                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
   2801                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
   2802                             ProcessRecord tmp = mLruProcesses.get(i);
   2803                             mLruProcesses.set(i, mLruProcesses.get(i-1));
   2804                             mLruProcesses.set(i-1, tmp);
   2805                             i--;
   2806                         }
   2807                     } else {
   2808                         // A gap, we can stop here.
   2809                         break;
   2810                     }
   2811                 }
   2812             } else {
   2813                 // Process has activities, put it at the very tipsy-top.
   2814                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
   2815                 mLruProcesses.add(app);
   2816             }
   2817             nextIndex = mLruProcessServiceStart;
   2818         } else if (hasService) {
   2819             // Process has services, put it at the top of the service list.
   2820             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
   2821             mLruProcesses.add(mLruProcessActivityStart, app);
   2822             nextIndex = mLruProcessServiceStart;
   2823             mLruProcessActivityStart++;
   2824         } else  {
   2825             // Process not otherwise of interest, it goes to the top of the non-service area.
   2826             int index = mLruProcessServiceStart;
   2827             if (client != null) {
   2828                 // If there is a client, don't allow the process to be moved up higher
   2829                 // in the list than that client.
   2830                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2831                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
   2832                         + " when updating " + app);
   2833                 if (clientIndex <= lrui) {
   2834                     // Don't allow the client index restriction to push it down farther in the
   2835                     // list than it already is.
   2836                     clientIndex = lrui;
   2837                 }
   2838                 if (clientIndex >= 0 && index > clientIndex) {
   2839                     index = clientIndex;
   2840                 }
   2841             }
   2842             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
   2843             mLruProcesses.add(index, app);
   2844             nextIndex = index-1;
   2845             mLruProcessActivityStart++;
   2846             mLruProcessServiceStart++;
   2847         }
   2848 
   2849         // If the app is currently using a content provider or service,
   2850         // bump those processes as well.
   2851         for (int j=app.connections.size()-1; j>=0; j--) {
   2852             ConnectionRecord cr = app.connections.valueAt(j);
   2853             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   2854                     && cr.binding.service.app != null
   2855                     && cr.binding.service.app.lruSeq != mLruSeq
   2856                     && !cr.binding.service.app.persistent) {
   2857                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   2858                         "service connection", cr, app);
   2859             }
   2860         }
   2861         for (int j=app.conProviders.size()-1; j>=0; j--) {
   2862             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   2863             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   2864                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   2865                         "provider reference", cpr, app);
   2866             }
   2867         }
   2868     }
   2869 
   2870     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   2871         if (uid == Process.SYSTEM_UID) {
   2872             // The system gets to run in any process.  If there are multiple
   2873             // processes with the same uid, just pick the first (this
   2874             // should never happen).
   2875             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   2876             if (procs == null) return null;
   2877             final int N = procs.size();
   2878             for (int i = 0; i < N; i++) {
   2879                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   2880             }
   2881         }
   2882         ProcessRecord proc = mProcessNames.get(processName, uid);
   2883         if (false && proc != null && !keepIfLarge
   2884                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   2885                 && proc.lastCachedPss >= 4000) {
   2886             // Turn this condition on to cause killing to happen regularly, for testing.
   2887             if (proc.baseProcessTracker != null) {
   2888                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2889             }
   2890             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2891         } else if (proc != null && !keepIfLarge
   2892                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   2893                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2894             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   2895             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   2896                 if (proc.baseProcessTracker != null) {
   2897                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2898                 }
   2899                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
   2900             }
   2901         }
   2902         return proc;
   2903     }
   2904 
   2905     void ensurePackageDexOpt(String packageName) {
   2906         IPackageManager pm = AppGlobals.getPackageManager();
   2907         try {
   2908             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
   2909                 mDidDexOpt = true;
   2910             }
   2911         } catch (RemoteException e) {
   2912         }
   2913     }
   2914 
   2915     boolean isNextTransitionForward() {
   2916         int transit = mWindowManager.getPendingAppTransition();
   2917         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2918                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2919                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2920     }
   2921 
   2922     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   2923             String processName, String abiOverride, int uid, Runnable crashHandler) {
   2924         synchronized(this) {
   2925             ApplicationInfo info = new ApplicationInfo();
   2926             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
   2927             // For isolated processes, the former contains the parent's uid and the latter the
   2928             // actual uid of the isolated process.
   2929             // In the special case introduced by this method (which is, starting an isolated
   2930             // process directly from the SystemServer without an actual parent app process) the
   2931             // closest thing to a parent's uid is SYSTEM_UID.
   2932             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
   2933             // the |isolated| logic in the ProcessRecord constructor.
   2934             info.uid = Process.SYSTEM_UID;
   2935             info.processName = processName;
   2936             info.className = entryPoint;
   2937             info.packageName = "android";
   2938             ProcessRecord proc = startProcessLocked(processName, info /* info */,
   2939                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
   2940                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
   2941                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
   2942                     crashHandler);
   2943             return proc != null ? proc.pid : 0;
   2944         }
   2945     }
   2946 
   2947     final ProcessRecord startProcessLocked(String processName,
   2948             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2949             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2950             boolean isolated, boolean keepIfLarge) {
   2951         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
   2952                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
   2953                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
   2954                 null /* crashHandler */);
   2955     }
   2956 
   2957     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
   2958             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
   2959             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
   2960             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
   2961         long startTime = SystemClock.elapsedRealtime();
   2962         ProcessRecord app;
   2963         if (!isolated) {
   2964             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   2965             checkTime(startTime, "startProcess: after getProcessRecord");
   2966         } else {
   2967             // If this is an isolated process, it can't re-use an existing process.
   2968             app = null;
   2969         }
   2970         // We don't have to do anything more if:
   2971         // (1) There is an existing application record; and
   2972         // (2) The caller doesn't think it is dead, OR there is no thread
   2973         //     object attached to it so we know it couldn't have crashed; and
   2974         // (3) There is a pid assigned to it, so it is either starting or
   2975         //     already running.
   2976         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2977                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2978                 + " thread=" + (app != null ? app.thread : null)
   2979                 + " pid=" + (app != null ? app.pid : -1));
   2980         if (app != null && app.pid > 0) {
   2981             if (!knownToBeDead || app.thread == null) {
   2982                 // We already have the app running, or are waiting for it to
   2983                 // come up (we have a pid but not yet its thread), so keep it.
   2984                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2985                 // If this is a new package in the process, add the package to the list
   2986                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
   2987                 checkTime(startTime, "startProcess: done, added package to proc");
   2988                 return app;
   2989             }
   2990 
   2991             // An application record is attached to a previous process,
   2992             // clean it up now.
   2993             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2994             checkTime(startTime, "startProcess: bad proc running, killing");
   2995             Process.killProcessGroup(app.info.uid, app.pid);
   2996             handleAppDiedLocked(app, true, true);
   2997             checkTime(startTime, "startProcess: done killing old proc");
   2998         }
   2999 
   3000         String hostingNameStr = hostingName != null
   3001                 ? hostingName.flattenToShortString() : null;
   3002 
   3003         if (!isolated) {
   3004             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   3005                 // If we are in the background, then check to see if this process
   3006                 // is bad.  If so, we will just silently fail.
   3007                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   3008                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   3009                             + "/" + info.processName);
   3010                     return null;
   3011                 }
   3012             } else {
   3013                 // When the user is explicitly starting a process, then clear its
   3014                 // crash count so that we won't make it bad until they see at
   3015                 // least one crash dialog again, and make the process good again
   3016                 // if it had been bad.
   3017                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   3018                         + "/" + info.processName);
   3019                 mProcessCrashTimes.remove(info.processName, info.uid);
   3020                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   3021                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   3022                             UserHandle.getUserId(info.uid), info.uid,
   3023                             info.processName);
   3024                     mBadProcesses.remove(info.processName, info.uid);
   3025                     if (app != null) {
   3026                         app.bad = false;
   3027                     }
   3028                 }
   3029             }
   3030         }
   3031 
   3032         if (app == null) {
   3033             checkTime(startTime, "startProcess: creating new process record");
   3034             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
   3035             app.crashHandler = crashHandler;
   3036             if (app == null) {
   3037                 Slog.w(TAG, "Failed making new process record for "
   3038                         + processName + "/" + info.uid + " isolated=" + isolated);
   3039                 return null;
   3040             }
   3041             mProcessNames.put(processName, app.uid, app);
   3042             if (isolated) {
   3043                 mIsolatedProcesses.put(app.uid, app);
   3044             }
   3045             checkTime(startTime, "startProcess: done creating new process record");
   3046         } else {
   3047             // If this is a new package in the process, add the package to the list
   3048             app.addPackage(info.packageName, info.versionCode, mProcessStats);
   3049             checkTime(startTime, "startProcess: added package to existing proc");
   3050         }
   3051 
   3052         // If the system is not ready yet, then hold off on starting this
   3053         // process until it is.
   3054         if (!mProcessesReady
   3055                 && !isAllowedWhileBooting(info)
   3056                 && !allowWhileBooting) {
   3057             if (!mProcessesOnHold.contains(app)) {
   3058                 mProcessesOnHold.add(app);
   3059             }
   3060             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   3061             checkTime(startTime, "startProcess: returning with proc on hold");
   3062             return app;
   3063         }
   3064 
   3065         checkTime(startTime, "startProcess: stepping in to startProcess");
   3066         startProcessLocked(
   3067                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
   3068         checkTime(startTime, "startProcess: done starting proc!");
   3069         return (app.pid != 0) ? app : null;
   3070     }
   3071 
   3072     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   3073         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   3074     }
   3075 
   3076     private final void startProcessLocked(ProcessRecord app,
   3077             String hostingType, String hostingNameStr) {
   3078         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
   3079                 null /* entryPoint */, null /* entryPointArgs */);
   3080     }
   3081 
   3082     private final void startProcessLocked(ProcessRecord app, String hostingType,
   3083             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
   3084         long startTime = SystemClock.elapsedRealtime();
   3085         if (app.pid > 0 && app.pid != MY_PID) {
   3086             checkTime(startTime, "startProcess: removing from pids map");
   3087             synchronized (mPidsSelfLocked) {
   3088                 mPidsSelfLocked.remove(app.pid);
   3089                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   3090             }
   3091             checkTime(startTime, "startProcess: done removing from pids map");
   3092             app.setPid(0);
   3093         }
   3094 
   3095         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   3096                 "startProcessLocked removing on hold: " + app);
   3097         mProcessesOnHold.remove(app);
   3098 
   3099         checkTime(startTime, "startProcess: starting to update cpu stats");
   3100         updateCpuStats();
   3101         checkTime(startTime, "startProcess: done updating cpu stats");
   3102 
   3103         try {
   3104             int uid = app.uid;
   3105 
   3106             int[] gids = null;
   3107             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   3108             if (!app.isolated) {
   3109                 int[] permGids = null;
   3110                 try {
   3111                     checkTime(startTime, "startProcess: getting gids from package manager");
   3112                     final PackageManager pm = mContext.getPackageManager();
   3113                     permGids = pm.getPackageGids(app.info.packageName);
   3114 
   3115                     if (Environment.isExternalStorageEmulated()) {
   3116                         checkTime(startTime, "startProcess: checking external storage perm");
   3117                         if (pm.checkPermission(
   3118                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   3119                                 app.info.packageName) == PERMISSION_GRANTED) {
   3120                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   3121                         } else {
   3122                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   3123                         }
   3124                     }
   3125                 } catch (PackageManager.NameNotFoundException e) {
   3126                     Slog.w(TAG, "Unable to retrieve gids", e);
   3127                 }
   3128 
   3129                 /*
   3130                  * Add shared application and profile GIDs so applications can share some
   3131                  * resources like shared libraries and access user-wide resources
   3132                  */
   3133                 if (permGids == null) {
   3134                     gids = new int[2];
   3135                 } else {
   3136                     gids = new int[permGids.length + 2];
   3137                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
   3138                 }
   3139                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   3140                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
   3141             }
   3142             checkTime(startTime, "startProcess: building args");
   3143             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
   3144                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3145                         && mTopComponent != null
   3146                         && app.processName.equals(mTopComponent.getPackageName())) {
   3147                     uid = 0;
   3148                 }
   3149                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
   3150                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   3151                     uid = 0;
   3152                 }
   3153             }
   3154             int debugFlags = 0;
   3155             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   3156                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   3157                 // Also turn on CheckJNI for debuggable apps. It's quite
   3158                 // awkward to turn on otherwise.
   3159                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3160             }
   3161             // Run the app in safe mode if its manifest requests so or the
   3162             // system is booted in safe mode.
   3163             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   3164                 mSafeMode == true) {
   3165                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   3166             }
   3167             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   3168                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   3169             }
   3170             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   3171                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   3172             }
   3173             if ("1".equals(SystemProperties.get("debug.assert"))) {
   3174                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   3175             }
   3176 
   3177             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
   3178             if (requiredAbi == null) {
   3179                 requiredAbi = Build.SUPPORTED_ABIS[0];
   3180             }
   3181 
   3182             String instructionSet = null;
   3183             if (app.info.primaryCpuAbi != null) {
   3184                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
   3185             }
   3186 
   3187             // Start the process.  It will either succeed and return a result containing
   3188             // the PID of the new process, or else throw a RuntimeException.
   3189             boolean isActivityProcess = (entryPoint == null);
   3190             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
   3191             checkTime(startTime, "startProcess: asking zygote to start proc");
   3192             Process.ProcessStartResult startResult = Process.start(entryPoint,
   3193                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   3194                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
   3195                     app.info.dataDir, entryPointArgs);
   3196             checkTime(startTime, "startProcess: returned from zygote!");
   3197 
   3198             if (app.isolated) {
   3199                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
   3200             }
   3201             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
   3202             checkTime(startTime, "startProcess: done updating battery stats");
   3203 
   3204             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   3205                     UserHandle.getUserId(uid), startResult.pid, uid,
   3206                     app.processName, hostingType,
   3207                     hostingNameStr != null ? hostingNameStr : "");
   3208 
   3209             if (app.persistent) {
   3210                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   3211             }
   3212 
   3213             checkTime(startTime, "startProcess: building log message");
   3214             StringBuilder buf = mStringBuilder;
   3215             buf.setLength(0);
   3216             buf.append("Start proc ");
   3217             buf.append(app.processName);
   3218             if (!isActivityProcess) {
   3219                 buf.append(" [");
   3220                 buf.append(entryPoint);
   3221                 buf.append("]");
   3222             }
   3223             buf.append(" for ");
   3224             buf.append(hostingType);
   3225             if (hostingNameStr != null) {
   3226                 buf.append(" ");
   3227                 buf.append(hostingNameStr);
   3228             }
   3229             buf.append(": pid=");
   3230             buf.append(startResult.pid);
   3231             buf.append(" uid=");
   3232             buf.append(uid);
   3233             buf.append(" gids={");
   3234             if (gids != null) {
   3235                 for (int gi=0; gi<gids.length; gi++) {
   3236                     if (gi != 0) buf.append(", ");
   3237                     buf.append(gids[gi]);
   3238 
   3239                 }
   3240             }
   3241             buf.append("}");
   3242             if (requiredAbi != null) {
   3243                 buf.append(" abi=");
   3244                 buf.append(requiredAbi);
   3245             }
   3246             Slog.i(TAG, buf.toString());
   3247             app.setPid(startResult.pid);
   3248             app.usingWrapper = startResult.usingWrapper;
   3249             app.removed = false;
   3250             app.killed = false;
   3251             app.killedByAm = false;
   3252             checkTime(startTime, "startProcess: starting to update pids map");
   3253             synchronized (mPidsSelfLocked) {
   3254                 this.mPidsSelfLocked.put(startResult.pid, app);
   3255                 if (isActivityProcess) {
   3256                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   3257                     msg.obj = app;
   3258                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   3259                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   3260                 }
   3261             }
   3262             checkTime(startTime, "startProcess: done updating pids map");
   3263         } catch (RuntimeException e) {
   3264             // XXX do better error recovery.
   3265             app.setPid(0);
   3266             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   3267             if (app.isolated) {
   3268                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   3269             }
   3270             Slog.e(TAG, "Failure starting process " + app.processName, e);
   3271         }
   3272     }
   3273 
   3274     void updateUsageStats(ActivityRecord component, boolean resumed) {
   3275         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
   3276         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3277         if (resumed) {
   3278             if (mUsageStatsService != null) {
   3279                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3280                         UsageEvents.Event.MOVE_TO_FOREGROUND);
   3281             }
   3282             synchronized (stats) {
   3283                 stats.noteActivityResumedLocked(component.app.uid);
   3284             }
   3285         } else {
   3286             if (mUsageStatsService != null) {
   3287                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
   3288                         UsageEvents.Event.MOVE_TO_BACKGROUND);
   3289             }
   3290             synchronized (stats) {
   3291                 stats.noteActivityPausedLocked(component.app.uid);
   3292             }
   3293         }
   3294     }
   3295 
   3296     Intent getHomeIntent() {
   3297         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   3298         intent.setComponent(mTopComponent);
   3299         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   3300             intent.addCategory(Intent.CATEGORY_HOME);
   3301         }
   3302         return intent;
   3303     }
   3304 
   3305     boolean startHomeActivityLocked(int userId) {
   3306         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
   3307                 && mTopAction == null) {
   3308             // We are running in factory test mode, but unable to find
   3309             // the factory test app, so just sit around displaying the
   3310             // error message and don't try to start anything.
   3311             return false;
   3312         }
   3313         Intent intent = getHomeIntent();
   3314         ActivityInfo aInfo =
   3315             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   3316         if (aInfo != null) {
   3317             intent.setComponent(new ComponentName(
   3318                     aInfo.applicationInfo.packageName, aInfo.name));
   3319             // Don't do this if the home app is currently being
   3320             // instrumented.
   3321             aInfo = new ActivityInfo(aInfo);
   3322             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   3323             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   3324                     aInfo.applicationInfo.uid, true);
   3325             if (app == null || app.instrumentationClass == null) {
   3326                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   3327                 mStackSupervisor.startHomeActivity(intent, aInfo);
   3328             }
   3329         }
   3330 
   3331         return true;
   3332     }
   3333 
   3334     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   3335         ActivityInfo ai = null;
   3336         ComponentName comp = intent.getComponent();
   3337         try {
   3338             if (comp != null) {
   3339                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   3340             } else {
   3341                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   3342                         intent,
   3343                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   3344                             flags, userId);
   3345 
   3346                 if (info != null) {
   3347                     ai = info.activityInfo;
   3348                 }
   3349             }
   3350         } catch (RemoteException e) {
   3351             // ignore
   3352         }
   3353 
   3354         return ai;
   3355     }
   3356 
   3357     /**
   3358      * Starts the "new version setup screen" if appropriate.
   3359      */
   3360     void startSetupActivityLocked() {
   3361         // Only do this once per boot.
   3362         if (mCheckedForSetup) {
   3363             return;
   3364         }
   3365 
   3366         // We will show this screen if the current one is a different
   3367         // version than the last one shown, and we are not running in
   3368         // low-level factory test mode.
   3369         final ContentResolver resolver = mContext.getContentResolver();
   3370         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
   3371                 Settings.Global.getInt(resolver,
   3372                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   3373             mCheckedForSetup = true;
   3374 
   3375             // See if we should be showing the platform update setup UI.
   3376             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   3377             List<ResolveInfo> ris = mContext.getPackageManager()
   3378                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   3379 
   3380             // We don't allow third party apps to replace this.
   3381             ResolveInfo ri = null;
   3382             for (int i=0; ris != null && i<ris.size(); i++) {
   3383                 if ((ris.get(i).activityInfo.applicationInfo.flags
   3384                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   3385                     ri = ris.get(i);
   3386                     break;
   3387                 }
   3388             }
   3389 
   3390             if (ri != null) {
   3391                 String vers = ri.activityInfo.metaData != null
   3392                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   3393                         : null;
   3394                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   3395                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   3396                             Intent.METADATA_SETUP_VERSION);
   3397                 }
   3398                 String lastVers = Settings.Secure.getString(
   3399                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   3400                 if (vers != null && !vers.equals(lastVers)) {
   3401                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   3402                     intent.setComponent(new ComponentName(
   3403                             ri.activityInfo.packageName, ri.activityInfo.name));
   3404                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
   3405                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
   3406                             null);
   3407                 }
   3408             }
   3409         }
   3410     }
   3411 
   3412     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   3413         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   3414     }
   3415 
   3416     void enforceNotIsolatedCaller(String caller) {
   3417         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   3418             throw new SecurityException("Isolated process not allowed to call " + caller);
   3419         }
   3420     }
   3421 
   3422     void enforceShellRestriction(String restriction, int userHandle) {
   3423         if (Binder.getCallingUid() == Process.SHELL_UID) {
   3424             if (userHandle < 0
   3425                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
   3426                 throw new SecurityException("Shell does not have permission to access user "
   3427                         + userHandle);
   3428             }
   3429         }
   3430     }
   3431 
   3432     @Override
   3433     public int getFrontActivityScreenCompatMode() {
   3434         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   3435         synchronized (this) {
   3436             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   3437         }
   3438     }
   3439 
   3440     @Override
   3441     public void setFrontActivityScreenCompatMode(int mode) {
   3442         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3443                 "setFrontActivityScreenCompatMode");
   3444         synchronized (this) {
   3445             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   3446         }
   3447     }
   3448 
   3449     @Override
   3450     public int getPackageScreenCompatMode(String packageName) {
   3451         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   3452         synchronized (this) {
   3453             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   3454         }
   3455     }
   3456 
   3457     @Override
   3458     public void setPackageScreenCompatMode(String packageName, int mode) {
   3459         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3460                 "setPackageScreenCompatMode");
   3461         synchronized (this) {
   3462             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   3463         }
   3464     }
   3465 
   3466     @Override
   3467     public boolean getPackageAskScreenCompat(String packageName) {
   3468         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   3469         synchronized (this) {
   3470             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   3471         }
   3472     }
   3473 
   3474     @Override
   3475     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   3476         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3477                 "setPackageAskScreenCompat");
   3478         synchronized (this) {
   3479             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   3480         }
   3481     }
   3482 
   3483     private void dispatchProcessesChanged() {
   3484         int N;
   3485         synchronized (this) {
   3486             N = mPendingProcessChanges.size();
   3487             if (mActiveProcessChanges.length < N) {
   3488                 mActiveProcessChanges = new ProcessChangeItem[N];
   3489             }
   3490             mPendingProcessChanges.toArray(mActiveProcessChanges);
   3491             mAvailProcessChanges.addAll(mPendingProcessChanges);
   3492             mPendingProcessChanges.clear();
   3493             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   3494         }
   3495 
   3496         int i = mProcessObservers.beginBroadcast();
   3497         while (i > 0) {
   3498             i--;
   3499             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3500             if (observer != null) {
   3501                 try {
   3502                     for (int j=0; j<N; j++) {
   3503                         ProcessChangeItem item = mActiveProcessChanges[j];
   3504                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   3505                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   3506                                     + item.pid + " uid=" + item.uid + ": "
   3507                                     + item.foregroundActivities);
   3508                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   3509                                     item.foregroundActivities);
   3510                         }
   3511                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
   3512                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
   3513                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
   3514                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
   3515                         }
   3516                     }
   3517                 } catch (RemoteException e) {
   3518                 }
   3519             }
   3520         }
   3521         mProcessObservers.finishBroadcast();
   3522     }
   3523 
   3524     private void dispatchProcessDied(int pid, int uid) {
   3525         int i = mProcessObservers.beginBroadcast();
   3526         while (i > 0) {
   3527             i--;
   3528             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3529             if (observer != null) {
   3530                 try {
   3531                     observer.onProcessDied(pid, uid);
   3532                 } catch (RemoteException e) {
   3533                 }
   3534             }
   3535         }
   3536         mProcessObservers.finishBroadcast();
   3537     }
   3538 
   3539     @Override
   3540     public final int startActivity(IApplicationThread caller, String callingPackage,
   3541             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3542             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
   3543         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   3544             resultWho, requestCode, startFlags, profilerInfo, options,
   3545             UserHandle.getCallingUserId());
   3546     }
   3547 
   3548     @Override
   3549     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   3550             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3551             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3552         enforceNotIsolatedCaller("startActivity");
   3553         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3554                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3555         // TODO: Switch to user app stacks here.
   3556         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3557                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3558                 profilerInfo, null, null, options, userId, null, null);
   3559     }
   3560 
   3561     @Override
   3562     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
   3563             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3564             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3565 
   3566         // This is very dangerous -- it allows you to perform a start activity (including
   3567         // permission grants) as any app that may launch one of your own activities.  So
   3568         // we will only allow this to be done from activities that are part of the core framework,
   3569         // and then only when they are running as the system.
   3570         final ActivityRecord sourceRecord;
   3571         final int targetUid;
   3572         final String targetPackage;
   3573         synchronized (this) {
   3574             if (resultTo == null) {
   3575                 throw new SecurityException("Must be called from an activity");
   3576             }
   3577             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
   3578             if (sourceRecord == null) {
   3579                 throw new SecurityException("Called with bad activity token: " + resultTo);
   3580             }
   3581             if (!sourceRecord.info.packageName.equals("android")) {
   3582                 throw new SecurityException(
   3583                         "Must be called from an activity that is declared in the android package");
   3584             }
   3585             if (sourceRecord.app == null) {
   3586                 throw new SecurityException("Called without a process attached to activity");
   3587             }
   3588             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
   3589                 // This is still okay, as long as this activity is running under the
   3590                 // uid of the original calling activity.
   3591                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
   3592                     throw new SecurityException(
   3593                             "Calling activity in uid " + sourceRecord.app.uid
   3594                                     + " must be system uid or original calling uid "
   3595                                     + sourceRecord.launchedFromUid);
   3596                 }
   3597             }
   3598             targetUid = sourceRecord.launchedFromUid;
   3599             targetPackage = sourceRecord.launchedFromPackage;
   3600         }
   3601 
   3602         if (userId == UserHandle.USER_NULL) {
   3603             userId = UserHandle.getUserId(sourceRecord.app.uid);
   3604         }
   3605 
   3606         // TODO: Switch to user app stacks here.
   3607         try {
   3608             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
   3609                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
   3610                     null, null, options, userId, null, null);
   3611             return ret;
   3612         } catch (SecurityException e) {
   3613             // XXX need to figure out how to propagate to original app.
   3614             // A SecurityException here is generally actually a fault of the original
   3615             // calling activity (such as a fairly granting permissions), so propagate it
   3616             // back to them.
   3617             /*
   3618             StringBuilder msg = new StringBuilder();
   3619             msg.append("While launching");
   3620             msg.append(intent.toString());
   3621             msg.append(": ");
   3622             msg.append(e.getMessage());
   3623             */
   3624             throw e;
   3625         }
   3626     }
   3627 
   3628     @Override
   3629     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   3630             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3631             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
   3632         enforceNotIsolatedCaller("startActivityAndWait");
   3633         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3634                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
   3635         WaitResult res = new WaitResult();
   3636         // TODO: Switch to user app stacks here.
   3637         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   3638                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
   3639                 options, userId, null, null);
   3640         return res;
   3641     }
   3642 
   3643     @Override
   3644     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   3645             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   3646             int startFlags, Configuration config, Bundle options, int userId) {
   3647         enforceNotIsolatedCaller("startActivityWithConfig");
   3648         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3649                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
   3650         // TODO: Switch to user app stacks here.
   3651         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3652                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3653                 null, null, config, options, userId, null, null);
   3654         return ret;
   3655     }
   3656 
   3657     @Override
   3658     public int startActivityIntentSender(IApplicationThread caller,
   3659             IntentSender intent, Intent fillInIntent, String resolvedType,
   3660             IBinder resultTo, String resultWho, int requestCode,
   3661             int flagsMask, int flagsValues, Bundle options) {
   3662         enforceNotIsolatedCaller("startActivityIntentSender");
   3663         // Refuse possible leaked file descriptors
   3664         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3665             throw new IllegalArgumentException("File descriptors passed in Intent");
   3666         }
   3667 
   3668         IIntentSender sender = intent.getTarget();
   3669         if (!(sender instanceof PendingIntentRecord)) {
   3670             throw new IllegalArgumentException("Bad PendingIntent object");
   3671         }
   3672 
   3673         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3674 
   3675         synchronized (this) {
   3676             // If this is coming from the currently resumed activity, it is
   3677             // effectively saying that app switches are allowed at this point.
   3678             final ActivityStack stack = getFocusedStack();
   3679             if (stack.mResumedActivity != null &&
   3680                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   3681                 mAppSwitchesAllowedTime = 0;
   3682             }
   3683         }
   3684         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   3685                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
   3686         return ret;
   3687     }
   3688 
   3689     @Override
   3690     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
   3691             Intent intent, String resolvedType, IVoiceInteractionSession session,
   3692             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
   3693             Bundle options, int userId) {
   3694         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
   3695                 != PackageManager.PERMISSION_GRANTED) {
   3696             String msg = "Permission Denial: startVoiceActivity() from pid="
   3697                     + Binder.getCallingPid()
   3698                     + ", uid=" + Binder.getCallingUid()
   3699                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
   3700             Slog.w(TAG, msg);
   3701             throw new SecurityException(msg);
   3702         }
   3703         if (session == null || interactor == null) {
   3704             throw new NullPointerException("null session or interactor");
   3705         }
   3706         userId = handleIncomingUser(callingPid, callingUid, userId,
   3707                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
   3708         // TODO: Switch to user app stacks here.
   3709         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
   3710                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
   3711                 null, options, userId, null, null);
   3712     }
   3713 
   3714     @Override
   3715     public boolean startNextMatchingActivity(IBinder callingActivity,
   3716             Intent intent, Bundle options) {
   3717         // Refuse possible leaked file descriptors
   3718         if (intent != null && intent.hasFileDescriptors() == true) {
   3719             throw new IllegalArgumentException("File descriptors passed in Intent");
   3720         }
   3721 
   3722         synchronized (this) {
   3723             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   3724             if (r == null) {
   3725                 ActivityOptions.abort(options);
   3726                 return false;
   3727             }
   3728             if (r.app == null || r.app.thread == null) {
   3729                 // The caller is not running...  d'oh!
   3730                 ActivityOptions.abort(options);
   3731                 return false;
   3732             }
   3733             intent = new Intent(intent);
   3734             // The caller is not allowed to change the data.
   3735             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3736             // And we are resetting to find the next component...
   3737             intent.setComponent(null);
   3738 
   3739             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3740 
   3741             ActivityInfo aInfo = null;
   3742             try {
   3743                 List<ResolveInfo> resolves =
   3744                     AppGlobals.getPackageManager().queryIntentActivities(
   3745                             intent, r.resolvedType,
   3746                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   3747                             UserHandle.getCallingUserId());
   3748 
   3749                 // Look for the original activity in the list...
   3750                 final int N = resolves != null ? resolves.size() : 0;
   3751                 for (int i=0; i<N; i++) {
   3752                     ResolveInfo rInfo = resolves.get(i);
   3753                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3754                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3755                         // We found the current one...  the next matching is
   3756                         // after it.
   3757                         i++;
   3758                         if (i<N) {
   3759                             aInfo = resolves.get(i).activityInfo;
   3760                         }
   3761                         if (debug) {
   3762                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   3763                                     + "/" + r.info.name);
   3764                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
   3765                                     + "/" + aInfo.name);
   3766                         }
   3767                         break;
   3768                     }
   3769                 }
   3770             } catch (RemoteException e) {
   3771             }
   3772 
   3773             if (aInfo == null) {
   3774                 // Nobody who is next!
   3775                 ActivityOptions.abort(options);
   3776                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   3777                 return false;
   3778             }
   3779 
   3780             intent.setComponent(new ComponentName(
   3781                     aInfo.applicationInfo.packageName, aInfo.name));
   3782             intent.setFlags(intent.getFlags()&~(
   3783                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3784                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3785                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3786                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3787 
   3788             // Okay now we need to start the new activity, replacing the
   3789             // currently running activity.  This is a little tricky because
   3790             // we want to start the new one as if the current one is finished,
   3791             // but not finish the current one first so that there is no flicker.
   3792             // And thus...
   3793             final boolean wasFinishing = r.finishing;
   3794             r.finishing = true;
   3795 
   3796             // Propagate reply information over to the new activity.
   3797             final ActivityRecord resultTo = r.resultTo;
   3798             final String resultWho = r.resultWho;
   3799             final int requestCode = r.requestCode;
   3800             r.resultTo = null;
   3801             if (resultTo != null) {
   3802                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3803             }
   3804 
   3805             final long origId = Binder.clearCallingIdentity();
   3806             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
   3807                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
   3808                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
   3809                     -1, r.launchedFromUid, 0, options, false, null, null, null);
   3810             Binder.restoreCallingIdentity(origId);
   3811 
   3812             r.finishing = wasFinishing;
   3813             if (res != ActivityManager.START_SUCCESS) {
   3814                 return false;
   3815             }
   3816             return true;
   3817         }
   3818     }
   3819 
   3820     @Override
   3821     public final int startActivityFromRecents(int taskId, Bundle options) {
   3822         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
   3823             String msg = "Permission Denial: startActivityFromRecents called without " +
   3824                     START_TASKS_FROM_RECENTS;
   3825             Slog.w(TAG, msg);
   3826             throw new SecurityException(msg);
   3827         }
   3828         return startActivityFromRecentsInner(taskId, options);
   3829     }
   3830 
   3831     final int startActivityFromRecentsInner(int taskId, Bundle options) {
   3832         final TaskRecord task;
   3833         final int callingUid;
   3834         final String callingPackage;
   3835         final Intent intent;
   3836         final int userId;
   3837         synchronized (this) {
   3838             task = recentTaskForIdLocked(taskId);
   3839             if (task == null) {
   3840                 throw new IllegalArgumentException("Task " + taskId + " not found.");
   3841             }
   3842             callingUid = task.mCallingUid;
   3843             callingPackage = task.mCallingPackage;
   3844             intent = task.intent;
   3845             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
   3846             userId = task.userId;
   3847         }
   3848         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
   3849                 options, userId, null, task);
   3850     }
   3851 
   3852     final int startActivityInPackage(int uid, String callingPackage,
   3853             Intent intent, String resolvedType, IBinder resultTo,
   3854             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
   3855             IActivityContainer container, TaskRecord inTask) {
   3856 
   3857         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3858                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3859 
   3860         // TODO: Switch to user app stacks here.
   3861         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
   3862                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
   3863                 null, null, null, options, userId, container, inTask);
   3864         return ret;
   3865     }
   3866 
   3867     @Override
   3868     public final int startActivities(IApplicationThread caller, String callingPackage,
   3869             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   3870             int userId) {
   3871         enforceNotIsolatedCaller("startActivities");
   3872         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3873                 false, ALLOW_FULL_ONLY, "startActivity", null);
   3874         // TODO: Switch to user app stacks here.
   3875         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
   3876                 resolvedTypes, resultTo, options, userId);
   3877         return ret;
   3878     }
   3879 
   3880     final int startActivitiesInPackage(int uid, String callingPackage,
   3881             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   3882             Bundle options, int userId) {
   3883 
   3884         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3885                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
   3886         // TODO: Switch to user app stacks here.
   3887         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   3888                 resultTo, options, userId);
   3889         return ret;
   3890     }
   3891 
   3892     //explicitly remove thd old information in mRecentTasks when removing existing user.
   3893     private void removeRecentTasksForUserLocked(int userId) {
   3894         if(userId <= 0) {
   3895             Slog.i(TAG, "Can't remove recent task on user " + userId);
   3896             return;
   3897         }
   3898 
   3899         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
   3900             TaskRecord tr = mRecentTasks.get(i);
   3901             if (tr.userId == userId) {
   3902                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
   3903                         + " when finishing user" + userId);
   3904                 mRecentTasks.remove(i);
   3905                 tr.removedFromRecents(mTaskPersister);
   3906             }
   3907         }
   3908 
   3909         // Remove tasks from persistent storage.
   3910         mTaskPersister.wakeup(null, true);
   3911     }
   3912 
   3913     // Sort by taskId
   3914     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
   3915         @Override
   3916         public int compare(TaskRecord lhs, TaskRecord rhs) {
   3917             return rhs.taskId - lhs.taskId;
   3918         }
   3919     };
   3920 
   3921     // Extract the affiliates of the chain containing mRecentTasks[start].
   3922     private int processNextAffiliateChain(int start) {
   3923         final TaskRecord startTask = mRecentTasks.get(start);
   3924         final int affiliateId = startTask.mAffiliatedTaskId;
   3925 
   3926         // Quick identification of isolated tasks. I.e. those not launched behind.
   3927         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
   3928                 startTask.mNextAffiliate == null) {
   3929             // There is still a slim chance that there are other tasks that point to this task
   3930             // and that the chain is so messed up that this task no longer points to them but
   3931             // the gain of this optimization outweighs the risk.
   3932             startTask.inRecents = true;
   3933             return start + 1;
   3934         }
   3935 
   3936         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
   3937         mTmpRecents.clear();
   3938         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
   3939             final TaskRecord task = mRecentTasks.get(i);
   3940             if (task.mAffiliatedTaskId == affiliateId) {
   3941                 mRecentTasks.remove(i);
   3942                 mTmpRecents.add(task);
   3943             }
   3944         }
   3945 
   3946         // Sort them all by taskId. That is the order they were create in and that order will
   3947         // always be correct.
   3948         Collections.sort(mTmpRecents, mTaskRecordComparator);
   3949 
   3950         // Go through and fix up the linked list.
   3951         // The first one is the end of the chain and has no next.
   3952         final TaskRecord first = mTmpRecents.get(0);
   3953         first.inRecents = true;
   3954         if (first.mNextAffiliate != null) {
   3955             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
   3956             first.setNextAffiliate(null);
   3957             mTaskPersister.wakeup(first, false);
   3958         }
   3959         // Everything in the middle is doubly linked from next to prev.
   3960         final int tmpSize = mTmpRecents.size();
   3961         for (int i = 0; i < tmpSize - 1; ++i) {
   3962             final TaskRecord next = mTmpRecents.get(i);
   3963             final TaskRecord prev = mTmpRecents.get(i + 1);
   3964             if (next.mPrevAffiliate != prev) {
   3965                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
   3966                         " setting prev=" + prev);
   3967                 next.setPrevAffiliate(prev);
   3968                 mTaskPersister.wakeup(next, false);
   3969             }
   3970             if (prev.mNextAffiliate != next) {
   3971                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
   3972                         " setting next=" + next);
   3973                 prev.setNextAffiliate(next);
   3974                 mTaskPersister.wakeup(prev, false);
   3975             }
   3976             prev.inRecents = true;
   3977         }
   3978         // The last one is the beginning of the list and has no prev.
   3979         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
   3980         if (last.mPrevAffiliate != null) {
   3981             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
   3982             last.setPrevAffiliate(null);
   3983             mTaskPersister.wakeup(last, false);
   3984         }
   3985 
   3986         // Insert the group back into mRecentTasks at start.
   3987         mRecentTasks.addAll(start, mTmpRecents);
   3988 
   3989         // Let the caller know where we left off.
   3990         return start + tmpSize;
   3991     }
   3992 
   3993     /**
   3994      * Update the recent tasks lists: make sure tasks should still be here (their
   3995      * applications / activities still exist), update their availability, fixup ordering
   3996      * of affiliations.
   3997      */
   3998     void cleanupRecentTasksLocked(int userId) {
   3999         if (mRecentTasks == null) {
   4000             // Happens when called from the packagemanager broadcast before boot.
   4001             return;
   4002         }
   4003 
   4004         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
   4005         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
   4006         final IPackageManager pm = AppGlobals.getPackageManager();
   4007         final ActivityInfo dummyAct = new ActivityInfo();
   4008         final ApplicationInfo dummyApp = new ApplicationInfo();
   4009 
   4010         int N = mRecentTasks.size();
   4011 
   4012         int[] users = userId == UserHandle.USER_ALL
   4013                 ? getUsersLocked() : new int[] { userId };
   4014         for (int user : users) {
   4015             for (int i = 0; i < N; i++) {
   4016                 TaskRecord task = mRecentTasks.get(i);
   4017                 if (task.userId != user) {
   4018                     // Only look at tasks for the user ID of interest.
   4019                     continue;
   4020                 }
   4021                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
   4022                     // This situation is broken, and we should just get rid of it now.
   4023                     mRecentTasks.remove(i);
   4024                     task.removedFromRecents(mTaskPersister);
   4025                     i--;
   4026                     N--;
   4027                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
   4028                     continue;
   4029                 }
   4030                 // Check whether this activity is currently available.
   4031                 if (task.realActivity != null) {
   4032                     ActivityInfo ai = availActCache.get(task.realActivity);
   4033                     if (ai == null) {
   4034                         try {
   4035                             ai = pm.getActivityInfo(task.realActivity,
   4036                                     PackageManager.GET_UNINSTALLED_PACKAGES
   4037                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
   4038                         } catch (RemoteException e) {
   4039                             // Will never happen.
   4040                             continue;
   4041                         }
   4042                         if (ai == null) {
   4043                             ai = dummyAct;
   4044                         }
   4045                         availActCache.put(task.realActivity, ai);
   4046                     }
   4047                     if (ai == dummyAct) {
   4048                         // This could be either because the activity no longer exists, or the
   4049                         // app is temporarily gone.  For the former we want to remove the recents
   4050                         // entry; for the latter we want to mark it as unavailable.
   4051                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
   4052                         if (app == null) {
   4053                             try {
   4054                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
   4055                                         PackageManager.GET_UNINSTALLED_PACKAGES
   4056                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
   4057                             } catch (RemoteException e) {
   4058                                 // Will never happen.
   4059                                 continue;
   4060                             }
   4061                             if (app == null) {
   4062                                 app = dummyApp;
   4063                             }
   4064                             availAppCache.put(task.realActivity.getPackageName(), app);
   4065                         }
   4066                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   4067                             // Doesn't exist any more!  Good-bye.
   4068                             mRecentTasks.remove(i);
   4069                             task.removedFromRecents(mTaskPersister);
   4070                             i--;
   4071                             N--;
   4072                             Slog.w(TAG, "Removing no longer valid recent: " + task);
   4073                             continue;
   4074                         } else {
   4075                             // Otherwise just not available for now.
   4076                             if (task.isAvailable) {
   4077                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   4078                                         + task);
   4079                             }
   4080                             task.isAvailable = false;
   4081                         }
   4082                     } else {
   4083                         if (!ai.enabled || !ai.applicationInfo.enabled
   4084                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
   4085                             if (task.isAvailable) {
   4086                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
   4087                                         + task + " (enabled=" + ai.enabled + "/"
   4088                                         + ai.applicationInfo.enabled +  " flags="
   4089                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
   4090                             }
   4091                             task.isAvailable = false;
   4092                         } else {
   4093                             if (!task.isAvailable) {
   4094                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
   4095                                         + task);
   4096                             }
   4097                             task.isAvailable = true;
   4098                         }
   4099                     }
   4100                 }
   4101             }
   4102         }
   4103 
   4104         // Verify the affiliate chain for each task.
   4105         for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
   4106         }
   4107 
   4108         mTmpRecents.clear();
   4109         // mRecentTasks is now in sorted, affiliated order.
   4110     }
   4111 
   4112     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
   4113         int N = mRecentTasks.size();
   4114         TaskRecord top = task;
   4115         int topIndex = taskIndex;
   4116         while (top.mNextAffiliate != null && topIndex > 0) {
   4117             top = top.mNextAffiliate;
   4118             topIndex--;
   4119         }
   4120         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
   4121                 + topIndex + " from intial " + taskIndex);
   4122         // Find the end of the chain, doing a sanity check along the way.
   4123         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
   4124         int endIndex = topIndex;
   4125         TaskRecord prev = top;
   4126         while (endIndex < N) {
   4127             TaskRecord cur = mRecentTasks.get(endIndex);
   4128             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
   4129                     + endIndex + " " + cur);
   4130             if (cur == top) {
   4131                 // Verify start of the chain.
   4132                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
   4133                     Slog.wtf(TAG, "Bad chain @" + endIndex
   4134                             + ": first task has next affiliate: " + prev);
   4135                     sane = false;
   4136                     break;
   4137                 }
   4138             } else {
   4139                 // Verify middle of the chain's next points back to the one before.
   4140                 if (cur.mNextAffiliate != prev
   4141                         || cur.mNextAffiliateTaskId != prev.taskId) {
   4142                     Slog.wtf(TAG, "Bad chain @" + endIndex
   4143                             + ": middle task " + cur + " @" + endIndex
   4144                             + " has bad next affiliate "
   4145                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
   4146                             + ", expected " + prev);
   4147                     sane = false;
   4148                     break;
   4149                 }
   4150             }
   4151             if (cur.mPrevAffiliateTaskId == -1) {
   4152                 // Chain ends here.
   4153                 if (cur.mPrevAffiliate != null) {
   4154                     Slog.wtf(TAG, "Bad chain @" + endIndex
   4155                             + ": last task " + cur + " has previous affiliate "
   4156                             + cur.mPrevAffiliate);
   4157                     sane = false;
   4158                 }
   4159                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
   4160                 break;
   4161             } else {
   4162                 // Verify middle of the chain's prev points to a valid item.
   4163                 if (cur.mPrevAffiliate == null) {
   4164                     Slog.wtf(TAG, "Bad chain @" + endIndex
   4165                             + ": task " + cur + " has previous affiliate "
   4166                             + cur.mPrevAffiliate + " but should be id "
   4167                             + cur.mPrevAffiliate);
   4168                     sane = false;
   4169                     break;
   4170                 }
   4171             }
   4172             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
   4173                 Slog.wtf(TAG, "Bad chain @" + endIndex
   4174                         + ": task " + cur + " has affiliated id "
   4175                         + cur.mAffiliatedTaskId + " but should be "
   4176                         + task.mAffiliatedTaskId);
   4177                 sane = false;
   4178                 break;
   4179             }
   4180             prev = cur;
   4181             endIndex++;
   4182             if (endIndex >= N) {
   4183                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
   4184                         + ": last task " + prev);
   4185                 sane = false;
   4186                 break;
   4187             }
   4188         }
   4189         if (sane) {
   4190             if (endIndex < taskIndex) {
   4191                 Slog.wtf(TAG, "Bad chain @" + endIndex
   4192                         + ": did not extend to task " + task + " @" + taskIndex);
   4193                 sane = false;
   4194             }
   4195         }
   4196         if (sane) {
   4197             // All looks good, we can just move all of the affiliated tasks
   4198             // to the top.
   4199             for (int i=topIndex; i<=endIndex; i++) {
   4200                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
   4201                         + " from " + i + " to " + (i-topIndex));
   4202                 TaskRecord cur = mRecentTasks.remove(i);
   4203                 mRecentTasks.add(i-topIndex, cur);
   4204             }
   4205             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
   4206                     + " to " + endIndex);
   4207             return true;
   4208         }
   4209 
   4210         // Whoops, couldn't do it.
   4211         return false;
   4212     }
   4213 
   4214     final void addRecentTaskLocked(TaskRecord task) {
   4215         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
   4216                 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
   4217 
   4218         int N = mRecentTasks.size();
   4219         // Quick case: check if the top-most recent task is the same.
   4220         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
   4221             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
   4222             return;
   4223         }
   4224         // Another quick case: check if this is part of a set of affiliated
   4225         // tasks that are at the top.
   4226         if (isAffiliated && N > 0 && task.inRecents
   4227                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
   4228             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
   4229                     + " at top when adding " + task);
   4230             return;
   4231         }
   4232         // Another quick case: never add voice sessions.
   4233         if (task.voiceSession != null) {
   4234             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
   4235             return;
   4236         }
   4237 
   4238         boolean needAffiliationFix = false;
   4239 
   4240         // Slightly less quick case: the task is already in recents, so all we need
   4241         // to do is move it.
   4242         if (task.inRecents) {
   4243             int taskIndex = mRecentTasks.indexOf(task);
   4244             if (taskIndex >= 0) {
   4245                 if (!isAffiliated) {
   4246                     // Simple case: this is not an affiliated task, so we just move it to the front.
   4247                     mRecentTasks.remove(taskIndex);
   4248                     mRecentTasks.add(0, task);
   4249                     notifyTaskPersisterLocked(task, false);
   4250                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
   4251                             + " from " + taskIndex);
   4252                     return;
   4253                 } else {
   4254                     // More complicated: need to keep all affiliated tasks together.
   4255                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4256                         // All went well.
   4257                         return;
   4258                     }
   4259 
   4260                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4261                     // everything and then go through our general path of adding a new task.
   4262                     needAffiliationFix = true;
   4263                 }
   4264             } else {
   4265                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
   4266                 needAffiliationFix = true;
   4267             }
   4268         }
   4269 
   4270         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
   4271         trimRecentsForTask(task, true);
   4272 
   4273         N = mRecentTasks.size();
   4274         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
   4275             final TaskRecord tr = mRecentTasks.remove(N - 1);
   4276             tr.removedFromRecents(mTaskPersister);
   4277             N--;
   4278         }
   4279         task.inRecents = true;
   4280         if (!isAffiliated || needAffiliationFix) {
   4281             // If this is a simple non-affiliated task, or we had some failure trying to
   4282             // handle it as part of an affilated task, then just place it at the top.
   4283             mRecentTasks.add(0, task);
   4284         } else if (isAffiliated) {
   4285             // If this is a new affiliated task, then move all of the affiliated tasks
   4286             // to the front and insert this new one.
   4287             TaskRecord other = task.mNextAffiliate;
   4288             if (other == null) {
   4289                 other = task.mPrevAffiliate;
   4290             }
   4291             if (other != null) {
   4292                 int otherIndex = mRecentTasks.indexOf(other);
   4293                 if (otherIndex >= 0) {
   4294                     // Insert new task at appropriate location.
   4295                     int taskIndex;
   4296                     if (other == task.mNextAffiliate) {
   4297                         // We found the index of our next affiliation, which is who is
   4298                         // before us in the list, so add after that point.
   4299                         taskIndex = otherIndex+1;
   4300                     } else {
   4301                         // We found the index of our previous affiliation, which is who is
   4302                         // after us in the list, so add at their position.
   4303                         taskIndex = otherIndex;
   4304                     }
   4305                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
   4306                             + taskIndex + ": " + task);
   4307                     mRecentTasks.add(taskIndex, task);
   4308 
   4309                     // Now move everything to the front.
   4310                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
   4311                         // All went well.
   4312                         return;
   4313                     }
   4314 
   4315                     // Uh oh...  something bad in the affiliation chain, try to rebuild
   4316                     // everything and then go through our general path of adding a new task.
   4317                     needAffiliationFix = true;
   4318                 } else {
   4319                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
   4320                             + other);
   4321                     needAffiliationFix = true;
   4322                 }
   4323             } else {
   4324                 if (DEBUG_RECENTS) Slog.d(TAG,
   4325                         "addRecent: adding affiliated task without next/prev:" + task);
   4326                 needAffiliationFix = true;
   4327             }
   4328         }
   4329         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
   4330 
   4331         if (needAffiliationFix) {
   4332             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
   4333             cleanupRecentTasksLocked(task.userId);
   4334         }
   4335     }
   4336 
   4337     /**
   4338      * If needed, remove oldest existing entries in recents that are for the same kind
   4339      * of task as the given one.
   4340      */
   4341     int trimRecentsForTask(TaskRecord task, boolean doTrim) {
   4342         int N = mRecentTasks.size();
   4343         final Intent intent = task.intent;
   4344         final boolean document = intent != null && intent.isDocument();
   4345 
   4346         int maxRecents = task.maxRecents - 1;
   4347         for (int i=0; i<N; i++) {
   4348             final TaskRecord tr = mRecentTasks.get(i);
   4349             if (task != tr) {
   4350                 if (task.userId != tr.userId) {
   4351                     continue;
   4352                 }
   4353                 if (i > MAX_RECENT_BITMAPS) {
   4354                     tr.freeLastThumbnail();
   4355                 }
   4356                 final Intent trIntent = tr.intent;
   4357                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
   4358                     (intent == null || !intent.filterEquals(trIntent))) {
   4359                     continue;
   4360                 }
   4361                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
   4362                 if (document && trIsDocument) {
   4363                     // These are the same document activity (not necessarily the same doc).
   4364                     if (maxRecents > 0) {
   4365                         --maxRecents;
   4366                         continue;
   4367                     }
   4368                     // Hit the maximum number of documents for this task. Fall through
   4369                     // and remove this document from recents.
   4370                 } else if (document || trIsDocument) {
   4371                     // Only one of these is a document. Not the droid we're looking for.
   4372                     continue;
   4373                 }
   4374             }
   4375 
   4376             if (!doTrim) {
   4377                 // If the caller is not actually asking for a trim, just tell them we reached
   4378                 // a point where the trim would happen.
   4379                 return i;
   4380             }
   4381 
   4382             // Either task and tr are the same or, their affinities match or their intents match
   4383             // and neither of them is a document, or they are documents using the same activity
   4384             // and their maxRecents has been reached.
   4385             tr.disposeThumbnail();
   4386             mRecentTasks.remove(i);
   4387             if (task != tr) {
   4388                 tr.removedFromRecents(mTaskPersister);
   4389             }
   4390             i--;
   4391             N--;
   4392             if (task.intent == null) {
   4393                 // If the new recent task we are adding is not fully
   4394                 // specified, then replace it with the existing recent task.
   4395                 task = tr;
   4396             }
   4397             notifyTaskPersisterLocked(tr, false);
   4398         }
   4399 
   4400         return -1;
   4401     }
   4402 
   4403     @Override
   4404     public void reportActivityFullyDrawn(IBinder token) {
   4405         synchronized (this) {
   4406             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4407             if (r == null) {
   4408                 return;
   4409             }
   4410             r.reportFullyDrawnLocked();
   4411         }
   4412     }
   4413 
   4414     @Override
   4415     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   4416         synchronized (this) {
   4417             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4418             if (r == null) {
   4419                 return;
   4420             }
   4421             final long origId = Binder.clearCallingIdentity();
   4422             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   4423             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   4424                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   4425             if (config != null) {
   4426                 r.frozenBeforeDestroy = true;
   4427                 if (!updateConfigurationLocked(config, r, false, false)) {
   4428                     mStackSupervisor.resumeTopActivitiesLocked();
   4429                 }
   4430             }
   4431             Binder.restoreCallingIdentity(origId);
   4432         }
   4433     }
   4434 
   4435     @Override
   4436     public int getRequestedOrientation(IBinder token) {
   4437         synchronized (this) {
   4438             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4439             if (r == null) {
   4440                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   4441             }
   4442             return mWindowManager.getAppOrientation(r.appToken);
   4443         }
   4444     }
   4445 
   4446     /**
   4447      * This is the internal entry point for handling Activity.finish().
   4448      *
   4449      * @param token The Binder token referencing the Activity we want to finish.
   4450      * @param resultCode Result code, if any, from this Activity.
   4451      * @param resultData Result data (Intent), if any, from this Activity.
   4452      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
   4453      *            the root Activity in the task.
   4454      *
   4455      * @return Returns true if the activity successfully finished, or false if it is still running.
   4456      */
   4457     @Override
   4458     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
   4459             boolean finishTask) {
   4460         // Refuse possible leaked file descriptors
   4461         if (resultData != null && resultData.hasFileDescriptors() == true) {
   4462             throw new IllegalArgumentException("File descriptors passed in Intent");
   4463         }
   4464 
   4465         synchronized(this) {
   4466             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4467             if (r == null) {
   4468                 return true;
   4469             }
   4470             // Keep track of the root activity of the task before we finish it
   4471             TaskRecord tr = r.task;
   4472             ActivityRecord rootR = tr.getRootActivity();
   4473             // Do not allow task to finish in Lock Task mode.
   4474             if (tr == mStackSupervisor.mLockTaskModeTask) {
   4475                 if (rootR == r) {
   4476                     mStackSupervisor.showLockTaskToast();
   4477                     return false;
   4478                 }
   4479             }
   4480             if (mController != null) {
   4481                 // Find the first activity that is not finishing.
   4482                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   4483                 if (next != null) {
   4484                     // ask watcher if this is allowed
   4485                     boolean resumeOK = true;
   4486                     try {
   4487                         resumeOK = mController.activityResuming(next.packageName);
   4488                     } catch (RemoteException e) {
   4489                         mController = null;
   4490                         Watchdog.getInstance().setActivityController(null);
   4491                     }
   4492 
   4493                     if (!resumeOK) {
   4494                         return false;
   4495                     }
   4496                 }
   4497             }
   4498             final long origId = Binder.clearCallingIdentity();
   4499             try {
   4500                 boolean res;
   4501                 if (finishTask && r == rootR) {
   4502                     // If requested, remove the task that is associated to this activity only if it
   4503                     // was the root activity in the task.  The result code and data is ignored because
   4504                     // we don't support returning them across task boundaries.
   4505                     res = removeTaskByIdLocked(tr.taskId, 0);
   4506                 } else {
   4507                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
   4508                             resultData, "app-request", true);
   4509                 }
   4510                 return res;
   4511             } finally {
   4512                 Binder.restoreCallingIdentity(origId);
   4513             }
   4514         }
   4515     }
   4516 
   4517     @Override
   4518     public final void finishHeavyWeightApp() {
   4519         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4520                 != PackageManager.PERMISSION_GRANTED) {
   4521             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   4522                     + Binder.getCallingPid()
   4523                     + ", uid=" + Binder.getCallingUid()
   4524                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4525             Slog.w(TAG, msg);
   4526             throw new SecurityException(msg);
   4527         }
   4528 
   4529         synchronized(this) {
   4530             if (mHeavyWeightProcess == null) {
   4531                 return;
   4532             }
   4533 
   4534             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   4535                     mHeavyWeightProcess.activities);
   4536             for (int i=0; i<activities.size(); i++) {
   4537                 ActivityRecord r = activities.get(i);
   4538                 if (!r.finishing) {
   4539                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   4540                             null, "finish-heavy", true);
   4541                 }
   4542             }
   4543 
   4544             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4545                     mHeavyWeightProcess.userId, 0));
   4546             mHeavyWeightProcess = null;
   4547         }
   4548     }
   4549 
   4550     @Override
   4551     public void crashApplication(int uid, int initialPid, String packageName,
   4552             String message) {
   4553         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4554                 != PackageManager.PERMISSION_GRANTED) {
   4555             String msg = "Permission Denial: crashApplication() from pid="
   4556                     + Binder.getCallingPid()
   4557                     + ", uid=" + Binder.getCallingUid()
   4558                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4559             Slog.w(TAG, msg);
   4560             throw new SecurityException(msg);
   4561         }
   4562 
   4563         synchronized(this) {
   4564             ProcessRecord proc = null;
   4565 
   4566             // Figure out which process to kill.  We don't trust that initialPid
   4567             // still has any relation to current pids, so must scan through the
   4568             // list.
   4569             synchronized (mPidsSelfLocked) {
   4570                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   4571                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   4572                     if (p.uid != uid) {
   4573                         continue;
   4574                     }
   4575                     if (p.pid == initialPid) {
   4576                         proc = p;
   4577                         break;
   4578                     }
   4579                     if (p.pkgList.containsKey(packageName)) {
   4580                         proc = p;
   4581                     }
   4582                 }
   4583             }
   4584 
   4585             if (proc == null) {
   4586                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   4587                         + " initialPid=" + initialPid
   4588                         + " packageName=" + packageName);
   4589                 return;
   4590             }
   4591 
   4592             if (proc.thread != null) {
   4593                 if (proc.pid == Process.myPid()) {
   4594                     Log.w(TAG, "crashApplication: trying to crash self!");
   4595                     return;
   4596                 }
   4597                 long ident = Binder.clearCallingIdentity();
   4598                 try {
   4599                     proc.thread.scheduleCrash(message);
   4600                 } catch (RemoteException e) {
   4601                 }
   4602                 Binder.restoreCallingIdentity(ident);
   4603             }
   4604         }
   4605     }
   4606 
   4607     @Override
   4608     public final void finishSubActivity(IBinder token, String resultWho,
   4609             int requestCode) {
   4610         synchronized(this) {
   4611             final long origId = Binder.clearCallingIdentity();
   4612             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4613             if (r != null) {
   4614                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   4615             }
   4616             Binder.restoreCallingIdentity(origId);
   4617         }
   4618     }
   4619 
   4620     @Override
   4621     public boolean finishActivityAffinity(IBinder token) {
   4622         synchronized(this) {
   4623             final long origId = Binder.clearCallingIdentity();
   4624             try {
   4625                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4626 
   4627                 ActivityRecord rootR = r.task.getRootActivity();
   4628                 // Do not allow task to finish in Lock Task mode.
   4629                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
   4630                     if (rootR == r) {
   4631                         mStackSupervisor.showLockTaskToast();
   4632                         return false;
   4633                     }
   4634                 }
   4635                 boolean res = false;
   4636                 if (r != null) {
   4637                     res = r.task.stack.finishActivityAffinityLocked(r);
   4638                 }
   4639                 return res;
   4640             } finally {
   4641                 Binder.restoreCallingIdentity(origId);
   4642             }
   4643         }
   4644     }
   4645 
   4646     @Override
   4647     public void finishVoiceTask(IVoiceInteractionSession session) {
   4648         synchronized(this) {
   4649             final long origId = Binder.clearCallingIdentity();
   4650             try {
   4651                 mStackSupervisor.finishVoiceTask(session);
   4652             } finally {
   4653                 Binder.restoreCallingIdentity(origId);
   4654             }
   4655         }
   4656 
   4657     }
   4658 
   4659     @Override
   4660     public boolean releaseActivityInstance(IBinder token) {
   4661         synchronized(this) {
   4662             final long origId = Binder.clearCallingIdentity();
   4663             try {
   4664                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
   4665                 if (r.task == null || r.task.stack == null) {
   4666                     return false;
   4667                 }
   4668                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
   4669             } finally {
   4670                 Binder.restoreCallingIdentity(origId);
   4671             }
   4672         }
   4673     }
   4674 
   4675     @Override
   4676     public void releaseSomeActivities(IApplicationThread appInt) {
   4677         synchronized(this) {
   4678             final long origId = Binder.clearCallingIdentity();
   4679             try {
   4680                 ProcessRecord app = getRecordForAppLocked(appInt);
   4681                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
   4682             } finally {
   4683                 Binder.restoreCallingIdentity(origId);
   4684             }
   4685         }
   4686     }
   4687 
   4688     @Override
   4689     public boolean willActivityBeVisible(IBinder token) {
   4690         synchronized(this) {
   4691             ActivityStack stack = ActivityRecord.getStackLocked(token);
   4692             if (stack != null) {
   4693                 return stack.willActivityBeVisibleLocked(token);
   4694             }
   4695             return false;
   4696         }
   4697     }
   4698 
   4699     @Override
   4700     public void overridePendingTransition(IBinder token, String packageName,
   4701             int enterAnim, int exitAnim) {
   4702         synchronized(this) {
   4703             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   4704             if (self == null) {
   4705                 return;
   4706             }
   4707 
   4708             final long origId = Binder.clearCallingIdentity();
   4709 
   4710             if (self.state == ActivityState.RESUMED
   4711                     || self.state == ActivityState.PAUSING) {
   4712                 mWindowManager.overridePendingAppTransition(packageName,
   4713                         enterAnim, exitAnim, null);
   4714             }
   4715 
   4716             Binder.restoreCallingIdentity(origId);
   4717         }
   4718     }
   4719 
   4720     /**
   4721      * Main function for removing an existing process from the activity manager
   4722      * as a result of that process going away.  Clears out all connections
   4723      * to the process.
   4724      */
   4725     private final void handleAppDiedLocked(ProcessRecord app,
   4726             boolean restarting, boolean allowRestart) {
   4727         int pid = app.pid;
   4728         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   4729         if (!kept && !restarting) {
   4730             removeLruProcessLocked(app);
   4731             if (pid > 0) {
   4732                 ProcessList.remove(pid);
   4733             }
   4734         }
   4735 
   4736         if (mProfileProc == app) {
   4737             clearProfilerLocked();
   4738         }
   4739 
   4740         // Remove this application's activities from active lists.
   4741         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   4742 
   4743         app.activities.clear();
   4744 
   4745         if (app.instrumentationClass != null) {
   4746             Slog.w(TAG, "Crash of app " + app.processName
   4747                   + " running instrumentation " + app.instrumentationClass);
   4748             Bundle info = new Bundle();
   4749             info.putString("shortMsg", "Process crashed.");
   4750             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   4751         }
   4752 
   4753         if (!restarting) {
   4754             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
   4755                 // If there was nothing to resume, and we are not already
   4756                 // restarting this process, but there is a visible activity that
   4757                 // is hosted by the process...  then make sure all visible
   4758                 // activities are running, taking care of restarting this
   4759                 // process.
   4760                 if (hasVisibleActivities) {
   4761                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   4762                 }
   4763             }
   4764         }
   4765     }
   4766 
   4767     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   4768         IBinder threadBinder = thread.asBinder();
   4769         // Find the application record.
   4770         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4771             ProcessRecord rec = mLruProcesses.get(i);
   4772             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   4773                 return i;
   4774             }
   4775         }
   4776         return -1;
   4777     }
   4778 
   4779     final ProcessRecord getRecordForAppLocked(
   4780             IApplicationThread thread) {
   4781         if (thread == null) {
   4782             return null;
   4783         }
   4784 
   4785         int appIndex = getLRURecordIndexForAppLocked(thread);
   4786         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   4787     }
   4788 
   4789     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   4790         // If there are no longer any background processes running,
   4791         // and the app that died was not running instrumentation,
   4792         // then tell everyone we are now low on memory.
   4793         boolean haveBg = false;
   4794         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4795             ProcessRecord rec = mLruProcesses.get(i);
   4796             if (rec.thread != null
   4797                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   4798                 haveBg = true;
   4799                 break;
   4800             }
   4801         }
   4802 
   4803         if (!haveBg) {
   4804             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   4805             if (doReport) {
   4806                 long now = SystemClock.uptimeMillis();
   4807                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   4808                     doReport = false;
   4809                 } else {
   4810                     mLastMemUsageReportTime = now;
   4811                 }
   4812             }
   4813             final ArrayList<ProcessMemInfo> memInfos
   4814                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   4815             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   4816             long now = SystemClock.uptimeMillis();
   4817             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   4818                 ProcessRecord rec = mLruProcesses.get(i);
   4819                 if (rec == dyingProc || rec.thread == null) {
   4820                     continue;
   4821                 }
   4822                 if (doReport) {
   4823                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   4824                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   4825                 }
   4826                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   4827                     // The low memory report is overriding any current
   4828                     // state for a GC request.  Make sure to do
   4829                     // heavy/important/visible/foreground processes first.
   4830                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   4831                         rec.lastRequestedGc = 0;
   4832                     } else {
   4833                         rec.lastRequestedGc = rec.lastLowMemory;
   4834                     }
   4835                     rec.reportLowMemory = true;
   4836                     rec.lastLowMemory = now;
   4837                     mProcessesToGc.remove(rec);
   4838                     addProcessToGcListLocked(rec);
   4839                 }
   4840             }
   4841             if (doReport) {
   4842                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   4843                 mHandler.sendMessage(msg);
   4844             }
   4845             scheduleAppGcsLocked();
   4846         }
   4847     }
   4848 
   4849     final void appDiedLocked(ProcessRecord app) {
   4850        appDiedLocked(app, app.pid, app.thread);
   4851     }
   4852 
   4853     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
   4854         // First check if this ProcessRecord is actually active for the pid.
   4855         synchronized (mPidsSelfLocked) {
   4856             ProcessRecord curProc = mPidsSelfLocked.get(pid);
   4857             if (curProc != app) {
   4858                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
   4859                 return;
   4860             }
   4861         }
   4862 
   4863         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   4864         synchronized (stats) {
   4865             stats.noteProcessDiedLocked(app.info.uid, pid);
   4866         }
   4867 
   4868         Process.killProcessQuiet(pid);
   4869         Process.killProcessGroup(app.info.uid, pid);
   4870         app.killed = true;
   4871 
   4872         // Clean up already done if the process has been re-started.
   4873         if (app.pid == pid && app.thread != null &&
   4874                 app.thread.asBinder() == thread.asBinder()) {
   4875             boolean doLowMem = app.instrumentationClass == null;
   4876             boolean doOomAdj = doLowMem;
   4877             if (!app.killedByAm) {
   4878                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4879                         + ") has died");
   4880                 mAllowLowerMemLevel = true;
   4881             } else {
   4882                 // Note that we always want to do oom adj to update our state with the
   4883                 // new number of procs.
   4884                 mAllowLowerMemLevel = false;
   4885                 doLowMem = false;
   4886             }
   4887             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4888             if (DEBUG_CLEANUP) Slog.v(
   4889                 TAG, "Dying app: " + app + ", pid: " + pid
   4890                 + ", thread: " + thread.asBinder());
   4891             handleAppDiedLocked(app, false, true);
   4892 
   4893             if (doOomAdj) {
   4894                 updateOomAdjLocked();
   4895             }
   4896             if (doLowMem) {
   4897                 doLowMemReportIfNeededLocked(app);
   4898             }
   4899         } else if (app.pid != pid) {
   4900             // A new process has already been started.
   4901             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   4902                     + ") has died and restarted (pid " + app.pid + ").");
   4903             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   4904         } else if (DEBUG_PROCESSES) {
   4905             Slog.d(TAG, "Received spurious death notification for thread "
   4906                     + thread.asBinder());
   4907         }
   4908     }
   4909 
   4910     /**
   4911      * If a stack trace dump file is configured, dump process stack traces.
   4912      * @param clearTraces causes the dump file to be erased prior to the new
   4913      *    traces being written, if true; when false, the new traces will be
   4914      *    appended to any existing file content.
   4915      * @param firstPids of dalvik VM processes to dump stack traces for first
   4916      * @param lastPids of dalvik VM processes to dump stack traces for last
   4917      * @param nativeProcs optional list of native process names to dump stack crawls
   4918      * @return file containing stack traces, or null if no dump file is configured
   4919      */
   4920     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   4921             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4922         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   4923         if (tracesPath == null || tracesPath.length() == 0) {
   4924             return null;
   4925         }
   4926 
   4927         File tracesFile = new File(tracesPath);
   4928         try {
   4929             File tracesDir = tracesFile.getParentFile();
   4930             if (!tracesDir.exists()) {
   4931                 tracesDir.mkdirs();
   4932                 if (!SELinux.restorecon(tracesDir)) {
   4933                     return null;
   4934                 }
   4935             }
   4936             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   4937 
   4938             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   4939             tracesFile.createNewFile();
   4940             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   4941         } catch (IOException e) {
   4942             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   4943             return null;
   4944         }
   4945 
   4946         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   4947         return tracesFile;
   4948     }
   4949 
   4950     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   4951             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   4952         // Use a FileObserver to detect when traces finish writing.
   4953         // The order of traces is considered important to maintain for legibility.
   4954         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   4955             @Override
   4956             public synchronized void onEvent(int event, String path) { notify(); }
   4957         };
   4958 
   4959         try {
   4960             observer.startWatching();
   4961 
   4962             // First collect all of the stacks of the most important pids.
   4963             if (firstPids != null) {
   4964                 try {
   4965                     int num = firstPids.size();
   4966                     for (int i = 0; i < num; i++) {
   4967                         synchronized (observer) {
   4968                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   4969                             observer.wait(200);  // Wait for write-close, give up after 200msec
   4970                         }
   4971                     }
   4972                 } catch (InterruptedException e) {
   4973                     Slog.wtf(TAG, e);
   4974                 }
   4975             }
   4976 
   4977             // Next collect the stacks of the native pids
   4978             if (nativeProcs != null) {
   4979                 int[] pids = Process.getPidsForCommands(nativeProcs);
   4980                 if (pids != null) {
   4981                     for (int pid : pids) {
   4982                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   4983                     }
   4984                 }
   4985             }
   4986 
   4987             // Lastly, measure CPU usage.
   4988             if (processCpuTracker != null) {
   4989                 processCpuTracker.init();
   4990                 System.gc();
   4991                 processCpuTracker.update();
   4992                 try {
   4993                     synchronized (processCpuTracker) {
   4994                         processCpuTracker.wait(500); // measure over 1/2 second.
   4995                     }
   4996                 } catch (InterruptedException e) {
   4997                 }
   4998                 processCpuTracker.update();
   4999 
   5000                 // We'll take the stack crawls of just the top apps using CPU.
   5001                 final int N = processCpuTracker.countWorkingStats();
   5002                 int numProcs = 0;
   5003                 for (int i=0; i<N && numProcs<5; i++) {
   5004                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   5005                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   5006                         numProcs++;
   5007                         try {
   5008                             synchronized (observer) {
   5009                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   5010                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   5011                             }
   5012                         } catch (InterruptedException e) {
   5013                             Slog.wtf(TAG, e);
   5014                         }
   5015 
   5016                     }
   5017                 }
   5018             }
   5019         } finally {
   5020             observer.stopWatching();
   5021         }
   5022     }
   5023 
   5024     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   5025         if (true || IS_USER_BUILD) {
   5026             return;
   5027         }
   5028         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   5029         if (tracesPath == null || tracesPath.length() == 0) {
   5030             return;
   5031         }
   5032 
   5033         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   5034         StrictMode.allowThreadDiskWrites();
   5035         try {
   5036             final File tracesFile = new File(tracesPath);
   5037             final File tracesDir = tracesFile.getParentFile();
   5038             final File tracesTmp = new File(tracesDir, "__tmp__");
   5039             try {
   5040                 if (!tracesDir.exists()) {
   5041                     tracesDir.mkdirs();
   5042                     if (!SELinux.restorecon(tracesDir.getPath())) {
   5043                         return;
   5044                     }
   5045                 }
   5046                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   5047 
   5048                 if (tracesFile.exists()) {
   5049                     tracesTmp.delete();
   5050                     tracesFile.renameTo(tracesTmp);
   5051                 }
   5052                 StringBuilder sb = new StringBuilder();
   5053                 Time tobj = new Time();
   5054                 tobj.set(System.currentTimeMillis());
   5055                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   5056                 sb.append(": ");
   5057                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   5058                 sb.append(" since ");
   5059                 sb.append(msg);
   5060                 FileOutputStream fos = new FileOutputStream(tracesFile);
   5061                 fos.write(sb.toString().getBytes());
   5062                 if (app == null) {
   5063                     fos.write("\n*** No application process!".getBytes());
   5064                 }
   5065                 fos.close();
   5066                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   5067             } catch (IOException e) {
   5068                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   5069                 return;
   5070             }
   5071 
   5072             if (app != null) {
   5073                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   5074                 firstPids.add(app.pid);
   5075                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   5076             }
   5077 
   5078             File lastTracesFile = null;
   5079             File curTracesFile = null;
   5080             for (int i=9; i>=0; i--) {
   5081                 String name = String.format(Locale.US, "slow%02d.txt", i);
   5082                 curTracesFile = new File(tracesDir, name);
   5083                 if (curTracesFile.exists()) {
   5084                     if (lastTracesFile != null) {
   5085                         curTracesFile.renameTo(lastTracesFile);
   5086                     } else {
   5087                         curTracesFile.delete();
   5088                     }
   5089                 }
   5090                 lastTracesFile = curTracesFile;
   5091             }
   5092             tracesFile.renameTo(curTracesFile);
   5093             if (tracesTmp.exists()) {
   5094                 tracesTmp.renameTo(tracesFile);
   5095             }
   5096         } finally {
   5097             StrictMode.setThreadPolicy(oldPolicy);
   5098         }
   5099     }
   5100 
   5101     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   5102             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   5103         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   5104         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   5105 
   5106         if (mController != null) {
   5107             try {
   5108                 // 0 == continue, -1 = kill process immediately
   5109                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   5110                 if (res < 0 && app.pid != MY_PID) {
   5111                     app.kill("anr", true);
   5112                 }
   5113             } catch (RemoteException e) {
   5114                 mController = null;
   5115                 Watchdog.getInstance().setActivityController(null);
   5116             }
   5117         }
   5118 
   5119         long anrTime = SystemClock.uptimeMillis();
   5120         if (MONITOR_CPU_USAGE) {
   5121             updateCpuStatsNow();
   5122         }
   5123 
   5124         synchronized (this) {
   5125             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   5126             if (mShuttingDown) {
   5127                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   5128                 return;
   5129             } else if (app.notResponding) {
   5130                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   5131                 return;
   5132             } else if (app.crashing) {
   5133                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   5134                 return;
   5135             }
   5136 
   5137             // In case we come through here for the same app before completing
   5138             // this one, mark as anring now so we will bail out.
   5139             app.notResponding = true;
   5140 
   5141             // Log the ANR to the event log.
   5142             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   5143                     app.processName, app.info.flags, annotation);
   5144 
   5145             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   5146             firstPids.add(app.pid);
   5147 
   5148             int parentPid = app.pid;
   5149             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   5150             if (parentPid != app.pid) firstPids.add(parentPid);
   5151 
   5152             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   5153 
   5154             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   5155                 ProcessRecord r = mLruProcesses.get(i);
   5156                 if (r != null && r.thread != null) {
   5157                     int pid = r.pid;
   5158                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   5159                         if (r.persistent) {
   5160                             firstPids.add(pid);
   5161                         } else {
   5162                             lastPids.put(pid, Boolean.TRUE);
   5163                         }
   5164                     }
   5165                 }
   5166             }
   5167         }
   5168 
   5169         // Log the ANR to the main log.
   5170         StringBuilder info = new StringBuilder();
   5171         info.setLength(0);
   5172         info.append("ANR in ").append(app.processName);
   5173         if (activity != null && activity.shortComponentName != null) {
   5174             info.append(" (").append(activity.shortComponentName).append(")");
   5175         }
   5176         info.append("\n");
   5177         info.append("PID: ").append(app.pid).append("\n");
   5178         if (annotation != null) {
   5179             info.append("Reason: ").append(annotation).append("\n");
   5180         }
   5181         if (parent != null && parent != activity) {
   5182             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   5183         }
   5184 
   5185         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
   5186 
   5187         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
   5188                 NATIVE_STACKS_OF_INTEREST);
   5189 
   5190         String cpuInfo = null;
   5191         if (MONITOR_CPU_USAGE) {
   5192             updateCpuStatsNow();
   5193             synchronized (mProcessCpuTracker) {
   5194                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
   5195             }
   5196             info.append(processCpuTracker.printCurrentLoad());
   5197             info.append(cpuInfo);
   5198         }
   5199 
   5200         info.append(processCpuTracker.printCurrentState(anrTime));
   5201 
   5202         Slog.e(TAG, info.toString());
   5203         if (tracesFile == null) {
   5204             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   5205             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   5206         }
   5207 
   5208         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   5209                 cpuInfo, tracesFile, null);
   5210 
   5211         if (mController != null) {
   5212             try {
   5213                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   5214                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   5215                 if (res != 0) {
   5216                     if (res < 0 && app.pid != MY_PID) {
   5217                         app.kill("anr", true);
   5218                     } else {
   5219                         synchronized (this) {
   5220                             mServices.scheduleServiceTimeoutLocked(app);
   5221                         }
   5222                     }
   5223                     return;
   5224                 }
   5225             } catch (RemoteException e) {
   5226                 mController = null;
   5227                 Watchdog.getInstance().setActivityController(null);
   5228             }
   5229         }
   5230 
   5231         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   5232         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   5233                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   5234 
   5235         synchronized (this) {
   5236             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   5237                 app.kill("bg anr", true);
   5238                 return;
   5239             }
   5240 
   5241             // Set the app's notResponding state, and look up the errorReportReceiver
   5242             makeAppNotRespondingLocked(app,
   5243                     activity != null ? activity.shortComponentName : null,
   5244                     annotation != null ? "ANR " + annotation : "ANR",
   5245                     info.toString());
   5246 
   5247             // Bring up the infamous App Not Responding dialog
   5248             Message msg = Message.obtain();
   5249             HashMap<String, Object> map = new HashMap<String, Object>();
   5250             msg.what = SHOW_NOT_RESPONDING_MSG;
   5251             msg.obj = map;
   5252             msg.arg1 = aboveSystem ? 1 : 0;
   5253             map.put("app", app);
   5254             if (activity != null) {
   5255                 map.put("activity", activity);
   5256             }
   5257 
   5258             mHandler.sendMessage(msg);
   5259         }
   5260     }
   5261 
   5262     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   5263         if (!mLaunchWarningShown) {
   5264             mLaunchWarningShown = true;
   5265             mHandler.post(new Runnable() {
   5266                 @Override
   5267                 public void run() {
   5268                     synchronized (ActivityManagerService.this) {
   5269                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   5270                         d.show();
   5271                         mHandler.postDelayed(new Runnable() {
   5272                             @Override
   5273                             public void run() {
   5274                                 synchronized (ActivityManagerService.this) {
   5275                                     d.dismiss();
   5276                                     mLaunchWarningShown = false;
   5277                                 }
   5278                             }
   5279                         }, 4000);
   5280                     }
   5281                 }
   5282             });
   5283         }
   5284     }
   5285 
   5286     @Override
   5287     public boolean clearApplicationUserData(final String packageName,
   5288             final IPackageDataObserver observer, int userId) {
   5289         enforceNotIsolatedCaller("clearApplicationUserData");
   5290         int uid = Binder.getCallingUid();
   5291         int pid = Binder.getCallingPid();
   5292         userId = handleIncomingUser(pid, uid,
   5293                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
   5294         long callingId = Binder.clearCallingIdentity();
   5295         try {
   5296             IPackageManager pm = AppGlobals.getPackageManager();
   5297             int pkgUid = -1;
   5298             synchronized(this) {
   5299                 try {
   5300                     pkgUid = pm.getPackageUid(packageName, userId);
   5301                 } catch (RemoteException e) {
   5302                 }
   5303                 if (pkgUid == -1) {
   5304                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5305                     if (observer != null) {
   5306                         try {
   5307                             observer.onRemoveCompleted(packageName, false);
   5308                         } catch (RemoteException e) {
   5309                             Slog.i(TAG, "Observer no longer exists.");
   5310                         }
   5311                     }
   5312                     return false;
   5313                 }
   5314                 if (uid == pkgUid || checkComponentPermission(
   5315                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   5316                         pid, uid, -1, true)
   5317                         == PackageManager.PERMISSION_GRANTED) {
   5318                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   5319                 } else {
   5320                     throw new SecurityException("PID " + pid + " does not have permission "
   5321                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
   5322                                     + " of package " + packageName);
   5323                 }
   5324 
   5325                 // Remove all tasks match the cleared application package and user
   5326                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
   5327                     final TaskRecord tr = mRecentTasks.get(i);
   5328                     final String taskPackageName =
   5329                             tr.getBaseIntent().getComponent().getPackageName();
   5330                     if (tr.userId != userId) continue;
   5331                     if (!taskPackageName.equals(packageName)) continue;
   5332                     removeTaskByIdLocked(tr.taskId, 0);
   5333                 }
   5334             }
   5335 
   5336             try {
   5337                 // Clear application user data
   5338                 pm.clearApplicationUserData(packageName, observer, userId);
   5339 
   5340                 synchronized(this) {
   5341                     // Remove all permissions granted from/to this package
   5342                     removeUriPermissionsForPackageLocked(packageName, userId, true);
   5343                 }
   5344 
   5345                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   5346                         Uri.fromParts("package", packageName, null));
   5347                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   5348                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   5349                         null, null, 0, null, null, null, false, false, userId);
   5350             } catch (RemoteException e) {
   5351             }
   5352         } finally {
   5353             Binder.restoreCallingIdentity(callingId);
   5354         }
   5355         return true;
   5356     }
   5357 
   5358     @Override
   5359     public void killBackgroundProcesses(final String packageName, int userId) {
   5360         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5361                 != PackageManager.PERMISSION_GRANTED &&
   5362                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   5363                         != PackageManager.PERMISSION_GRANTED) {
   5364             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   5365                     + Binder.getCallingPid()
   5366                     + ", uid=" + Binder.getCallingUid()
   5367                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5368             Slog.w(TAG, msg);
   5369             throw new SecurityException(msg);
   5370         }
   5371 
   5372         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   5373                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
   5374         long callingId = Binder.clearCallingIdentity();
   5375         try {
   5376             IPackageManager pm = AppGlobals.getPackageManager();
   5377             synchronized(this) {
   5378                 int appId = -1;
   5379                 try {
   5380                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   5381                 } catch (RemoteException e) {
   5382                 }
   5383                 if (appId == -1) {
   5384                     Slog.w(TAG, "Invalid packageName: " + packageName);
   5385                     return;
   5386                 }
   5387                 killPackageProcessesLocked(packageName, appId, userId,
   5388                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   5389             }
   5390         } finally {
   5391             Binder.restoreCallingIdentity(callingId);
   5392         }
   5393     }
   5394 
   5395     @Override
   5396     public void killAllBackgroundProcesses() {
   5397         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   5398                 != PackageManager.PERMISSION_GRANTED) {
   5399             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   5400                     + Binder.getCallingPid()
   5401                     + ", uid=" + Binder.getCallingUid()
   5402                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   5403             Slog.w(TAG, msg);
   5404             throw new SecurityException(msg);
   5405         }
   5406 
   5407         long callingId = Binder.clearCallingIdentity();
   5408         try {
   5409             synchronized(this) {
   5410                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5411                 final int NP = mProcessNames.getMap().size();
   5412                 for (int ip=0; ip<NP; ip++) {
   5413                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5414                     final int NA = apps.size();
   5415                     for (int ia=0; ia<NA; ia++) {
   5416                         ProcessRecord app = apps.valueAt(ia);
   5417                         if (app.persistent) {
   5418                             // we don't kill persistent processes
   5419                             continue;
   5420                         }
   5421                         if (app.removed) {
   5422                             procs.add(app);
   5423                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   5424                             app.removed = true;
   5425                             procs.add(app);
   5426                         }
   5427                     }
   5428                 }
   5429 
   5430                 int N = procs.size();
   5431                 for (int i=0; i<N; i++) {
   5432                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   5433                 }
   5434                 mAllowLowerMemLevel = true;
   5435                 updateOomAdjLocked();
   5436                 doLowMemReportIfNeededLocked(null);
   5437             }
   5438         } finally {
   5439             Binder.restoreCallingIdentity(callingId);
   5440         }
   5441     }
   5442 
   5443     @Override
   5444     public void forceStopPackage(final String packageName, int userId) {
   5445         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   5446                 != PackageManager.PERMISSION_GRANTED) {
   5447             String msg = "Permission Denial: forceStopPackage() from pid="
   5448                     + Binder.getCallingPid()
   5449                     + ", uid=" + Binder.getCallingUid()
   5450                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   5451             Slog.w(TAG, msg);
   5452             throw new SecurityException(msg);
   5453         }
   5454         final int callingPid = Binder.getCallingPid();
   5455         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
   5456                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
   5457         long callingId = Binder.clearCallingIdentity();
   5458         try {
   5459             IPackageManager pm = AppGlobals.getPackageManager();
   5460             synchronized(this) {
   5461                 int[] users = userId == UserHandle.USER_ALL
   5462                         ? getUsersLocked() : new int[] { userId };
   5463                 for (int user : users) {
   5464                     int pkgUid = -1;
   5465                     try {
   5466                         pkgUid = pm.getPackageUid(packageName, user);
   5467                     } catch (RemoteException e) {
   5468                     }
   5469                     if (pkgUid == -1) {
   5470                         Slog.w(TAG, "Invalid packageName: " + packageName);
   5471                         continue;
   5472                     }
   5473                     try {
   5474                         pm.setPackageStoppedState(packageName, true, user);
   5475                     } catch (RemoteException e) {
   5476                     } catch (IllegalArgumentException e) {
   5477                         Slog.w(TAG, "Failed trying to unstop package "
   5478                                 + packageName + ": " + e);
   5479                     }
   5480                     if (isUserRunningLocked(user, false)) {
   5481                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   5482                     }
   5483                 }
   5484             }
   5485         } finally {
   5486             Binder.restoreCallingIdentity(callingId);
   5487         }
   5488     }
   5489 
   5490     @Override
   5491     public void addPackageDependency(String packageName) {
   5492         synchronized (this) {
   5493             int callingPid = Binder.getCallingPid();
   5494             if (callingPid == Process.myPid()) {
   5495                 //  Yeah, um, no.
   5496                 Slog.w(TAG, "Can't addPackageDependency on system process");
   5497                 return;
   5498             }
   5499             ProcessRecord proc;
   5500             synchronized (mPidsSelfLocked) {
   5501                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   5502             }
   5503             if (proc != null) {
   5504                 if (proc.pkgDeps == null) {
   5505                     proc.pkgDeps = new ArraySet<String>(1);
   5506                 }
   5507                 proc.pkgDeps.add(packageName);
   5508             }
   5509         }
   5510     }
   5511 
   5512     /*
   5513      * The pkg name and app id have to be specified.
   5514      */
   5515     @Override
   5516     public void killApplicationWithAppId(String pkg, int appid, String reason) {
   5517         if (pkg == null) {
   5518             return;
   5519         }
   5520         // Make sure the uid is valid.
   5521         if (appid < 0) {
   5522             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   5523             return;
   5524         }
   5525         int callerUid = Binder.getCallingUid();
   5526         // Only the system server can kill an application
   5527         if (callerUid == Process.SYSTEM_UID) {
   5528             // Post an aysnc message to kill the application
   5529             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   5530             msg.arg1 = appid;
   5531             msg.arg2 = 0;
   5532             Bundle bundle = new Bundle();
   5533             bundle.putString("pkg", pkg);
   5534             bundle.putString("reason", reason);
   5535             msg.obj = bundle;
   5536             mHandler.sendMessage(msg);
   5537         } else {
   5538             throw new SecurityException(callerUid + " cannot kill pkg: " +
   5539                     pkg);
   5540         }
   5541     }
   5542 
   5543     @Override
   5544     public void closeSystemDialogs(String reason) {
   5545         enforceNotIsolatedCaller("closeSystemDialogs");
   5546 
   5547         final int pid = Binder.getCallingPid();
   5548         final int uid = Binder.getCallingUid();
   5549         final long origId = Binder.clearCallingIdentity();
   5550         try {
   5551             synchronized (this) {
   5552                 // Only allow this from foreground processes, so that background
   5553                 // applications can't abuse it to prevent system UI from being shown.
   5554                 if (uid >= Process.FIRST_APPLICATION_UID) {
   5555                     ProcessRecord proc;
   5556                     synchronized (mPidsSelfLocked) {
   5557                         proc = mPidsSelfLocked.get(pid);
   5558                     }
   5559                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   5560                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   5561                                 + " from background process " + proc);
   5562                         return;
   5563                     }
   5564                 }
   5565                 closeSystemDialogsLocked(reason);
   5566             }
   5567         } finally {
   5568             Binder.restoreCallingIdentity(origId);
   5569         }
   5570     }
   5571 
   5572     void closeSystemDialogsLocked(String reason) {
   5573         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   5574         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5575                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5576         if (reason != null) {
   5577             intent.putExtra("reason", reason);
   5578         }
   5579         mWindowManager.closeSystemDialogs(reason);
   5580 
   5581         mStackSupervisor.closeSystemDialogsLocked();
   5582 
   5583         broadcastIntentLocked(null, null, intent, null,
   5584                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   5585                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   5586     }
   5587 
   5588     @Override
   5589     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   5590         enforceNotIsolatedCaller("getProcessMemoryInfo");
   5591         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   5592         for (int i=pids.length-1; i>=0; i--) {
   5593             ProcessRecord proc;
   5594             int oomAdj;
   5595             synchronized (this) {
   5596                 synchronized (mPidsSelfLocked) {
   5597                     proc = mPidsSelfLocked.get(pids[i]);
   5598                     oomAdj = proc != null ? proc.setAdj : 0;
   5599                 }
   5600             }
   5601             infos[i] = new Debug.MemoryInfo();
   5602             Debug.getMemoryInfo(pids[i], infos[i]);
   5603             if (proc != null) {
   5604                 synchronized (this) {
   5605                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5606                         // Record this for posterity if the process has been stable.
   5607                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   5608                                 infos[i].getTotalUss(), false, proc.pkgList);
   5609                     }
   5610                 }
   5611             }
   5612         }
   5613         return infos;
   5614     }
   5615 
   5616     @Override
   5617     public long[] getProcessPss(int[] pids) {
   5618         enforceNotIsolatedCaller("getProcessPss");
   5619         long[] pss = new long[pids.length];
   5620         for (int i=pids.length-1; i>=0; i--) {
   5621             ProcessRecord proc;
   5622             int oomAdj;
   5623             synchronized (this) {
   5624                 synchronized (mPidsSelfLocked) {
   5625                     proc = mPidsSelfLocked.get(pids[i]);
   5626                     oomAdj = proc != null ? proc.setAdj : 0;
   5627                 }
   5628             }
   5629             long[] tmpUss = new long[1];
   5630             pss[i] = Debug.getPss(pids[i], tmpUss);
   5631             if (proc != null) {
   5632                 synchronized (this) {
   5633                     if (proc.thread != null && proc.setAdj == oomAdj) {
   5634                         // Record this for posterity if the process has been stable.
   5635                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   5636                     }
   5637                 }
   5638             }
   5639         }
   5640         return pss;
   5641     }
   5642 
   5643     @Override
   5644     public void killApplicationProcess(String processName, int uid) {
   5645         if (processName == null) {
   5646             return;
   5647         }
   5648 
   5649         int callerUid = Binder.getCallingUid();
   5650         // Only the system server can kill an application
   5651         if (callerUid == Process.SYSTEM_UID) {
   5652             synchronized (this) {
   5653                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   5654                 if (app != null && app.thread != null) {
   5655                     try {
   5656                         app.thread.scheduleSuicide();
   5657                     } catch (RemoteException e) {
   5658                         // If the other end already died, then our work here is done.
   5659                     }
   5660                 } else {
   5661                     Slog.w(TAG, "Process/uid not found attempting kill of "
   5662                             + processName + " / " + uid);
   5663                 }
   5664             }
   5665         } else {
   5666             throw new SecurityException(callerUid + " cannot kill app process: " +
   5667                     processName);
   5668         }
   5669     }
   5670 
   5671     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   5672         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   5673                 false, true, false, false, UserHandle.getUserId(uid), reason);
   5674         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   5675                 Uri.fromParts("package", packageName, null));
   5676         if (!mProcessesReady) {
   5677             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5678                     | Intent.FLAG_RECEIVER_FOREGROUND);
   5679         }
   5680         intent.putExtra(Intent.EXTRA_UID, uid);
   5681         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   5682         broadcastIntentLocked(null, null, intent,
   5683                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5684                 false, false,
   5685                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   5686     }
   5687 
   5688     private void forceStopUserLocked(int userId, String reason) {
   5689         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
   5690         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   5691         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   5692                 | Intent.FLAG_RECEIVER_FOREGROUND);
   5693         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   5694         broadcastIntentLocked(null, null, intent,
   5695                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   5696                 false, false,
   5697                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   5698     }
   5699 
   5700     private final boolean killPackageProcessesLocked(String packageName, int appId,
   5701             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   5702             boolean doit, boolean evenPersistent, String reason) {
   5703         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   5704 
   5705         // Remove all processes this package may have touched: all with the
   5706         // same UID (except for the system or root user), and all whose name
   5707         // matches the package name.
   5708         final int NP = mProcessNames.getMap().size();
   5709         for (int ip=0; ip<NP; ip++) {
   5710             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   5711             final int NA = apps.size();
   5712             for (int ia=0; ia<NA; ia++) {
   5713                 ProcessRecord app = apps.valueAt(ia);
   5714                 if (app.persistent && !evenPersistent) {
   5715                     // we don't kill persistent processes
   5716                     continue;
   5717                 }
   5718                 if (app.removed) {
   5719                     if (doit) {
   5720                         procs.add(app);
   5721                     }
   5722                     continue;
   5723                 }
   5724 
   5725                 // Skip process if it doesn't meet our oom adj requirement.
   5726                 if (app.setAdj < minOomAdj) {
   5727                     continue;
   5728                 }
   5729 
   5730                 // If no package is specified, we call all processes under the
   5731                 // give user id.
   5732                 if (packageName == null) {
   5733                     if (app.userId != userId) {
   5734                         continue;
   5735                     }
   5736                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   5737                         continue;
   5738                     }
   5739                 // Package has been specified, we want to hit all processes
   5740                 // that match it.  We need to qualify this by the processes
   5741                 // that are running under the specified app and user ID.
   5742                 } else {
   5743                     final boolean isDep = app.pkgDeps != null
   5744                             && app.pkgDeps.contains(packageName);
   5745                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
   5746                         continue;
   5747                     }
   5748                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   5749                         continue;
   5750                     }
   5751                     if (!app.pkgList.containsKey(packageName) && !isDep) {
   5752                         continue;
   5753                     }
   5754                 }
   5755 
   5756                 // Process has passed all conditions, kill it!
   5757                 if (!doit) {
   5758                     return true;
   5759                 }
   5760                 app.removed = true;
   5761                 procs.add(app);
   5762             }
   5763         }
   5764 
   5765         int N = procs.size();
   5766         for (int i=0; i<N; i++) {
   5767             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   5768         }
   5769         updateOomAdjLocked();
   5770         return N > 0;
   5771     }
   5772 
   5773     private final boolean forceStopPackageLocked(String name, int appId,
   5774             boolean callerWillRestart, boolean purgeCache, boolean doit,
   5775             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   5776         int i;
   5777         int N;
   5778 
   5779         if (userId == UserHandle.USER_ALL && name == null) {
   5780             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   5781         }
   5782 
   5783         if (appId < 0 && name != null) {
   5784             try {
   5785                 appId = UserHandle.getAppId(
   5786                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   5787             } catch (RemoteException e) {
   5788             }
   5789         }
   5790 
   5791         if (doit) {
   5792             if (name != null) {
   5793                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
   5794                         + " user=" + userId + ": " + reason);
   5795             } else {
   5796                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   5797             }
   5798 
   5799             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   5800             for (int ip=pmap.size()-1; ip>=0; ip--) {
   5801                 SparseArray<Long> ba = pmap.valueAt(ip);
   5802                 for (i=ba.size()-1; i>=0; i--) {
   5803                     boolean remove = false;
   5804                     final int entUid = ba.keyAt(i);
   5805                     if (name != null) {
   5806                         if (userId == UserHandle.USER_ALL) {
   5807                             if (UserHandle.getAppId(entUid) == appId) {
   5808                                 remove = true;
   5809                             }
   5810                         } else {
   5811                             if (entUid == UserHandle.getUid(userId, appId)) {
   5812                                 remove = true;
   5813                             }
   5814                         }
   5815                     } else if (UserHandle.getUserId(entUid) == userId) {
   5816                         remove = true;
   5817                     }
   5818                     if (remove) {
   5819                         ba.removeAt(i);
   5820                     }
   5821                 }
   5822                 if (ba.size() == 0) {
   5823                     pmap.removeAt(ip);
   5824                 }
   5825             }
   5826         }
   5827 
   5828         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   5829                 -100, callerWillRestart, true, doit, evenPersistent,
   5830                 name == null ? ("stop user " + userId) : ("stop " + name));
   5831 
   5832         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   5833             if (!doit) {
   5834                 return true;
   5835             }
   5836             didSomething = true;
   5837         }
   5838 
   5839         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   5840             if (!doit) {
   5841                 return true;
   5842             }
   5843             didSomething = true;
   5844         }
   5845 
   5846         if (name == null) {
   5847             // Remove all sticky broadcasts from this user.
   5848             mStickyBroadcasts.remove(userId);
   5849         }
   5850 
   5851         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   5852         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   5853                 userId, providers)) {
   5854             if (!doit) {
   5855                 return true;
   5856             }
   5857             didSomething = true;
   5858         }
   5859         N = providers.size();
   5860         for (i=0; i<N; i++) {
   5861             removeDyingProviderLocked(null, providers.get(i), true);
   5862         }
   5863 
   5864         // Remove transient permissions granted from/to this package/user
   5865         removeUriPermissionsForPackageLocked(name, userId, false);
   5866 
   5867         if (name == null || uninstalling) {
   5868             // Remove pending intents.  For now we only do this when force
   5869             // stopping users, because we have some problems when doing this
   5870             // for packages -- app widgets are not currently cleaned up for
   5871             // such packages, so they can be left with bad pending intents.
   5872             if (mIntentSenderRecords.size() > 0) {
   5873                 Iterator<WeakReference<PendingIntentRecord>> it
   5874                         = mIntentSenderRecords.values().iterator();
   5875                 while (it.hasNext()) {
   5876                     WeakReference<PendingIntentRecord> wpir = it.next();
   5877                     if (wpir == null) {
   5878                         it.remove();
   5879                         continue;
   5880                     }
   5881                     PendingIntentRecord pir = wpir.get();
   5882                     if (pir == null) {
   5883                         it.remove();
   5884                         continue;
   5885                     }
   5886                     if (name == null) {
   5887                         // Stopping user, remove all objects for the user.
   5888                         if (pir.key.userId != userId) {
   5889                             // Not the same user, skip it.
   5890                             continue;
   5891                         }
   5892                     } else {
   5893                         if (UserHandle.getAppId(pir.uid) != appId) {
   5894                             // Different app id, skip it.
   5895                             continue;
   5896                         }
   5897                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   5898                             // Different user, skip it.
   5899                             continue;
   5900                         }
   5901                         if (!pir.key.packageName.equals(name)) {
   5902                             // Different package, skip it.
   5903                             continue;
   5904                         }
   5905                     }
   5906                     if (!doit) {
   5907                         return true;
   5908                     }
   5909                     didSomething = true;
   5910                     it.remove();
   5911                     pir.canceled = true;
   5912                     if (pir.key.activity != null) {
   5913                         pir.key.activity.pendingResults.remove(pir.ref);
   5914                     }
   5915                 }
   5916             }
   5917         }
   5918 
   5919         if (doit) {
   5920             if (purgeCache && name != null) {
   5921                 AttributeCache ac = AttributeCache.instance();
   5922                 if (ac != null) {
   5923                     ac.removePackage(name);
   5924                 }
   5925             }
   5926             if (mBooted) {
   5927                 mStackSupervisor.resumeTopActivitiesLocked();
   5928                 mStackSupervisor.scheduleIdleLocked();
   5929             }
   5930         }
   5931 
   5932         return didSomething;
   5933     }
   5934 
   5935     private final boolean removeProcessLocked(ProcessRecord app,
   5936             boolean callerWillRestart, boolean allowRestart, String reason) {
   5937         final String name = app.processName;
   5938         final int uid = app.uid;
   5939         if (DEBUG_PROCESSES) Slog.d(
   5940             TAG, "Force removing proc " + app.toShortString() + " (" + name
   5941             + "/" + uid + ")");
   5942 
   5943         mProcessNames.remove(name, uid);
   5944         mIsolatedProcesses.remove(app.uid);
   5945         if (mHeavyWeightProcess == app) {
   5946             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5947                     mHeavyWeightProcess.userId, 0));
   5948             mHeavyWeightProcess = null;
   5949         }
   5950         boolean needRestart = false;
   5951         if (app.pid > 0 && app.pid != MY_PID) {
   5952             int pid = app.pid;
   5953             synchronized (mPidsSelfLocked) {
   5954                 mPidsSelfLocked.remove(pid);
   5955                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   5956             }
   5957             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   5958             if (app.isolated) {
   5959                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   5960             }
   5961             app.kill(reason, true);
   5962             handleAppDiedLocked(app, true, allowRestart);
   5963             removeLruProcessLocked(app);
   5964 
   5965             if (app.persistent && !app.isolated) {
   5966                 if (!callerWillRestart) {
   5967                     addAppLocked(app.info, false, null /* ABI override */);
   5968                 } else {
   5969                     needRestart = true;
   5970                 }
   5971             }
   5972         } else {
   5973             mRemovedProcesses.add(app);
   5974         }
   5975 
   5976         return needRestart;
   5977     }
   5978 
   5979     private final void processStartTimedOutLocked(ProcessRecord app) {
   5980         final int pid = app.pid;
   5981         boolean gone = false;
   5982         synchronized (mPidsSelfLocked) {
   5983             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   5984             if (knownApp != null && knownApp.thread == null) {
   5985                 mPidsSelfLocked.remove(pid);
   5986                 gone = true;
   5987             }
   5988         }
   5989 
   5990         if (gone) {
   5991             Slog.w(TAG, "Process " + app + " failed to attach");
   5992             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   5993                     pid, app.uid, app.processName);
   5994             mProcessNames.remove(app.processName, app.uid);
   5995             mIsolatedProcesses.remove(app.uid);
   5996             if (mHeavyWeightProcess == app) {
   5997                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   5998                         mHeavyWeightProcess.userId, 0));
   5999                 mHeavyWeightProcess = null;
   6000             }
   6001             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   6002             if (app.isolated) {
   6003                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   6004             }
   6005             // Take care of any launching providers waiting for this process.
   6006             checkAppInLaunchingProvidersLocked(app, true);
   6007             // Take care of any services that are waiting for the process.
   6008             mServices.processStartTimedOutLocked(app);
   6009             app.kill("start timeout", true);
   6010             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   6011                 Slog.w(TAG, "Unattached app died before backup, skipping");
   6012                 try {
   6013                     IBackupManager bm = IBackupManager.Stub.asInterface(
   6014                             ServiceManager.getService(Context.BACKUP_SERVICE));
   6015                     bm.agentDisconnected(app.info.packageName);
   6016                 } catch (RemoteException e) {
   6017                     // Can't happen; the backup manager is local
   6018                 }
   6019             }
   6020             if (isPendingBroadcastProcessLocked(pid)) {
   6021                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   6022                 skipPendingBroadcastLocked(pid);
   6023             }
   6024         } else {
   6025             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   6026         }
   6027     }
   6028 
   6029     private final boolean attachApplicationLocked(IApplicationThread thread,
   6030             int pid) {
   6031 
   6032         // Find the application record that is being attached...  either via
   6033         // the pid if we are running in multiple processes, or just pull the
   6034         // next app record if we are emulating process with anonymous threads.
   6035         ProcessRecord app;
   6036         if (pid != MY_PID && pid >= 0) {
   6037             synchronized (mPidsSelfLocked) {
   6038                 app = mPidsSelfLocked.get(pid);
   6039             }
   6040         } else {
   6041             app = null;
   6042         }
   6043 
   6044         if (app == null) {
   6045             Slog.w(TAG, "No pending application record for pid " + pid
   6046                     + " (IApplicationThread " + thread + "); dropping process");
   6047             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   6048             if (pid > 0 && pid != MY_PID) {
   6049                 Process.killProcessQuiet(pid);
   6050                 //TODO: Process.killProcessGroup(app.info.uid, pid);
   6051             } else {
   6052                 try {
   6053                     thread.scheduleExit();
   6054                 } catch (Exception e) {
   6055                     // Ignore exceptions.
   6056                 }
   6057             }
   6058             return false;
   6059         }
   6060 
   6061         // If this application record is still attached to a previous
   6062         // process, clean it up now.
   6063         if (app.thread != null) {
   6064             handleAppDiedLocked(app, true, true);
   6065         }
   6066 
   6067         // Tell the process all about itself.
   6068 
   6069         if (localLOGV) Slog.v(
   6070                 TAG, "Binding process pid " + pid + " to record " + app);
   6071 
   6072         final String processName = app.processName;
   6073         try {
   6074             AppDeathRecipient adr = new AppDeathRecipient(
   6075                     app, pid, thread);
   6076             thread.asBinder().linkToDeath(adr, 0);
   6077             app.deathRecipient = adr;
   6078         } catch (RemoteException e) {
   6079             app.resetPackageList(mProcessStats);
   6080             startProcessLocked(app, "link fail", processName);
   6081             return false;
   6082         }
   6083 
   6084         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   6085 
   6086         app.makeActive(thread, mProcessStats);
   6087         app.curAdj = app.setAdj = -100;
   6088         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
   6089         app.forcingToForeground = null;
   6090         updateProcessForegroundLocked(app, false, false);
   6091         app.hasShownUi = false;
   6092         app.debugging = false;
   6093         app.cached = false;
   6094 
   6095         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   6096 
   6097         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   6098         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   6099 
   6100         if (!normalMode) {
   6101             Slog.i(TAG, "Launching preboot mode app: " + app);
   6102         }
   6103 
   6104         if (localLOGV) Slog.v(
   6105             TAG, "New app record " + app
   6106             + " thread=" + thread.asBinder() + " pid=" + pid);
   6107         try {
   6108             int testMode = IApplicationThread.DEBUG_OFF;
   6109             if (mDebugApp != null && mDebugApp.equals(processName)) {
   6110                 testMode = mWaitForDebugger
   6111                     ? IApplicationThread.DEBUG_WAIT
   6112                     : IApplicationThread.DEBUG_ON;
   6113                 app.debugging = true;
   6114                 if (mDebugTransient) {
   6115                     mDebugApp = mOrigDebugApp;
   6116                     mWaitForDebugger = mOrigWaitForDebugger;
   6117                 }
   6118             }
   6119             String profileFile = app.instrumentationProfileFile;
   6120             ParcelFileDescriptor profileFd = null;
   6121             int samplingInterval = 0;
   6122             boolean profileAutoStop = false;
   6123             if (mProfileApp != null && mProfileApp.equals(processName)) {
   6124                 mProfileProc = app;
   6125                 profileFile = mProfileFile;
   6126                 profileFd = mProfileFd;
   6127                 samplingInterval = mSamplingInterval;
   6128                 profileAutoStop = mAutoStopProfiler;
   6129             }
   6130             boolean enableOpenGlTrace = false;
   6131             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   6132                 enableOpenGlTrace = true;
   6133                 mOpenGlTraceApp = null;
   6134             }
   6135 
   6136             // If the app is being launched for restore or full backup, set it up specially
   6137             boolean isRestrictedBackupMode = false;
   6138             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   6139                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   6140                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   6141                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   6142             }
   6143 
   6144             ensurePackageDexOpt(app.instrumentationInfo != null
   6145                     ? app.instrumentationInfo.packageName
   6146                     : app.info.packageName);
   6147             if (app.instrumentationClass != null) {
   6148                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   6149             }
   6150             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   6151                     + processName + " with config " + mConfiguration);
   6152             ApplicationInfo appInfo = app.instrumentationInfo != null
   6153                     ? app.instrumentationInfo : app.info;
   6154             app.compat = compatibilityInfoForPackageLocked(appInfo);
   6155             if (profileFd != null) {
   6156                 profileFd = profileFd.dup();
   6157             }
   6158             ProfilerInfo profilerInfo = profileFile == null ? null
   6159                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
   6160             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
   6161                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
   6162                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   6163                     isRestrictedBackupMode || !normalMode, app.persistent,
   6164                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   6165                     mCoreSettingsObserver.getCoreSettingsLocked());
   6166             updateLruProcessLocked(app, false, null);
   6167             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   6168         } catch (Exception e) {
   6169             // todo: Yikes!  What should we do?  For now we will try to
   6170             // start another process, but that could easily get us in
   6171             // an infinite loop of restarting processes...
   6172             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
   6173 
   6174             app.resetPackageList(mProcessStats);
   6175             app.unlinkDeathRecipient();
   6176             startProcessLocked(app, "bind fail", processName);
   6177             return false;
   6178         }
   6179 
   6180         // Remove this record from the list of starting applications.
   6181         mPersistentStartingProcesses.remove(app);
   6182         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   6183                 "Attach application locked removing on hold: " + app);
   6184         mProcessesOnHold.remove(app);
   6185 
   6186         boolean badApp = false;
   6187         boolean didSomething = false;
   6188 
   6189         // See if the top visible activity is waiting to run in this process...
   6190         if (normalMode) {
   6191             try {
   6192                 if (mStackSupervisor.attachApplicationLocked(app)) {
   6193                     didSomething = true;
   6194                 }
   6195             } catch (Exception e) {
   6196                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
   6197                 badApp = true;
   6198             }
   6199         }
   6200 
   6201         // Find any services that should be running in this process...
   6202         if (!badApp) {
   6203             try {
   6204                 didSomething |= mServices.attachApplicationLocked(app, processName);
   6205             } catch (Exception e) {
   6206                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
   6207                 badApp = true;
   6208             }
   6209         }
   6210 
   6211         // Check if a next-broadcast receiver is in this process...
   6212         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   6213             try {
   6214                 didSomething |= sendPendingBroadcastsLocked(app);
   6215             } catch (Exception e) {
   6216                 // If the app died trying to launch the receiver we declare it 'bad'
   6217                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
   6218                 badApp = true;
   6219             }
   6220         }
   6221 
   6222         // Check whether the next backup agent is in this process...
   6223         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   6224             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   6225             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   6226             try {
   6227                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   6228                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   6229                         mBackupTarget.backupMode);
   6230             } catch (Exception e) {
   6231                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
   6232                 badApp = true;
   6233             }
   6234         }
   6235 
   6236         if (badApp) {
   6237             app.kill("error during init", true);
   6238             handleAppDiedLocked(app, false, true);
   6239             return false;
   6240         }
   6241 
   6242         if (!didSomething) {
   6243             updateOomAdjLocked();
   6244         }
   6245 
   6246         return true;
   6247     }
   6248 
   6249     @Override
   6250     public final void attachApplication(IApplicationThread thread) {
   6251         synchronized (this) {
   6252             int callingPid = Binder.getCallingPid();
   6253             final long origId = Binder.clearCallingIdentity();
   6254             attachApplicationLocked(thread, callingPid);
   6255             Binder.restoreCallingIdentity(origId);
   6256         }
   6257     }
   6258 
   6259     @Override
   6260     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   6261         final long origId = Binder.clearCallingIdentity();
   6262         synchronized (this) {
   6263             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6264             if (stack != null) {
   6265                 ActivityRecord r =
   6266                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   6267                 if (stopProfiling) {
   6268                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   6269                         try {
   6270                             mProfileFd.close();
   6271                         } catch (IOException e) {
   6272                         }
   6273                         clearProfilerLocked();
   6274                     }
   6275                 }
   6276             }
   6277         }
   6278         Binder.restoreCallingIdentity(origId);
   6279     }
   6280 
   6281     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
   6282         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
   6283                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
   6284     }
   6285 
   6286     void enableScreenAfterBoot() {
   6287         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   6288                 SystemClock.uptimeMillis());
   6289         mWindowManager.enableScreenAfterBoot();
   6290 
   6291         synchronized (this) {
   6292             updateEventDispatchingLocked();
   6293         }
   6294     }
   6295 
   6296     @Override
   6297     public void showBootMessage(final CharSequence msg, final boolean always) {
   6298         enforceNotIsolatedCaller("showBootMessage");
   6299         mWindowManager.showBootMessage(msg, always);
   6300     }
   6301 
   6302     @Override
   6303     public void keyguardWaitingForActivityDrawn() {
   6304         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
   6305         final long token = Binder.clearCallingIdentity();
   6306         try {
   6307             synchronized (this) {
   6308                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   6309                 mWindowManager.keyguardWaitingForActivityDrawn();
   6310                 if (mLockScreenShown) {
   6311                     mLockScreenShown = false;
   6312                     comeOutOfSleepIfNeededLocked();
   6313                 }
   6314             }
   6315         } finally {
   6316             Binder.restoreCallingIdentity(token);
   6317         }
   6318     }
   6319 
   6320     final void finishBooting() {
   6321         synchronized (this) {
   6322             if (!mBootAnimationComplete) {
   6323                 mCallFinishBooting = true;
   6324                 return;
   6325             }
   6326             mCallFinishBooting = false;
   6327         }
   6328 
   6329         // Register receivers to handle package update events
   6330         mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
   6331 
   6332         // Let system services know.
   6333         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
   6334 
   6335         synchronized (this) {
   6336             // Ensure that any processes we had put on hold are now started
   6337             // up.
   6338             final int NP = mProcessesOnHold.size();
   6339             if (NP > 0) {
   6340                 ArrayList<ProcessRecord> procs =
   6341                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   6342                 for (int ip=0; ip<NP; ip++) {
   6343                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   6344                             + procs.get(ip));
   6345                     startProcessLocked(procs.get(ip), "on-hold", null);
   6346                 }
   6347             }
   6348 
   6349             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   6350                 // Start looking for apps that are abusing wake locks.
   6351                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   6352                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   6353                 // Tell anyone interested that we are done booting!
   6354                 SystemProperties.set("sys.boot_completed", "1");
   6355 
   6356                 // And trigger dev.bootcomplete if we are not showing encryption progress
   6357                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
   6358                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
   6359                     SystemProperties.set("dev.bootcomplete", "1");
   6360                 }
   6361                 for (int i=0; i<mStartedUsers.size(); i++) {
   6362                     UserStartedState uss = mStartedUsers.valueAt(i);
   6363                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   6364                         uss.mState = UserStartedState.STATE_RUNNING;
   6365                         final int userId = mStartedUsers.keyAt(i);
   6366                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   6367                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   6368                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   6369                         broadcastIntentLocked(null, null, intent, null,
   6370                                 new IIntentReceiver.Stub() {
   6371                                     @Override
   6372                                     public void performReceive(Intent intent, int resultCode,
   6373                                             String data, Bundle extras, boolean ordered,
   6374                                             boolean sticky, int sendingUser) {
   6375                                         synchronized (ActivityManagerService.this) {
   6376                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   6377                                                     true, false);
   6378                                         }
   6379                                     }
   6380                                 },
   6381                                 0, null, null,
   6382                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   6383                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
   6384                                 userId);
   6385                     }
   6386                 }
   6387                 scheduleStartProfilesLocked();
   6388             }
   6389         }
   6390     }
   6391 
   6392     @Override
   6393     public void bootAnimationComplete() {
   6394         final boolean callFinishBooting;
   6395         synchronized (this) {
   6396             callFinishBooting = mCallFinishBooting;
   6397             mBootAnimationComplete = true;
   6398         }
   6399         if (callFinishBooting) {
   6400             finishBooting();
   6401         }
   6402     }
   6403 
   6404     final void ensureBootCompleted() {
   6405         boolean booting;
   6406         boolean enableScreen;
   6407         synchronized (this) {
   6408             booting = mBooting;
   6409             mBooting = false;
   6410             enableScreen = !mBooted;
   6411             mBooted = true;
   6412         }
   6413 
   6414         if (booting) {
   6415             finishBooting();
   6416         }
   6417 
   6418         if (enableScreen) {
   6419             enableScreenAfterBoot();
   6420         }
   6421     }
   6422 
   6423     @Override
   6424     public final void activityResumed(IBinder token) {
   6425         final long origId = Binder.clearCallingIdentity();
   6426         synchronized(this) {
   6427             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6428             if (stack != null) {
   6429                 ActivityRecord.activityResumedLocked(token);
   6430             }
   6431         }
   6432         Binder.restoreCallingIdentity(origId);
   6433     }
   6434 
   6435     @Override
   6436     public final void activityPaused(IBinder token) {
   6437         final long origId = Binder.clearCallingIdentity();
   6438         synchronized(this) {
   6439             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6440             if (stack != null) {
   6441                 stack.activityPausedLocked(token, false);
   6442             }
   6443         }
   6444         Binder.restoreCallingIdentity(origId);
   6445     }
   6446 
   6447     @Override
   6448     public final void activityStopped(IBinder token, Bundle icicle,
   6449             PersistableBundle persistentState, CharSequence description) {
   6450         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
   6451 
   6452         // Refuse possible leaked file descriptors
   6453         if (icicle != null && icicle.hasFileDescriptors()) {
   6454             throw new IllegalArgumentException("File descriptors passed in Bundle");
   6455         }
   6456 
   6457         final long origId = Binder.clearCallingIdentity();
   6458 
   6459         synchronized (this) {
   6460             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6461             if (r != null) {
   6462                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
   6463             }
   6464         }
   6465 
   6466         trimApplications();
   6467 
   6468         Binder.restoreCallingIdentity(origId);
   6469     }
   6470 
   6471     @Override
   6472     public final void activityDestroyed(IBinder token) {
   6473         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   6474         synchronized (this) {
   6475             ActivityStack stack = ActivityRecord.getStackLocked(token);
   6476             if (stack != null) {
   6477                 stack.activityDestroyedLocked(token);
   6478             }
   6479         }
   6480     }
   6481 
   6482     @Override
   6483     public final void backgroundResourcesReleased(IBinder token) {
   6484         final long origId = Binder.clearCallingIdentity();
   6485         try {
   6486             synchronized (this) {
   6487                 ActivityStack stack = ActivityRecord.getStackLocked(token);
   6488                 if (stack != null) {
   6489                     stack.backgroundResourcesReleased(token);
   6490                 }
   6491             }
   6492         } finally {
   6493             Binder.restoreCallingIdentity(origId);
   6494         }
   6495     }
   6496 
   6497     @Override
   6498     public final void notifyLaunchTaskBehindComplete(IBinder token) {
   6499         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
   6500     }
   6501 
   6502     @Override
   6503     public final void notifyEnterAnimationComplete(IBinder token) {
   6504         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
   6505     }
   6506 
   6507     @Override
   6508     public String getCallingPackage(IBinder token) {
   6509         synchronized (this) {
   6510             ActivityRecord r = getCallingRecordLocked(token);
   6511             return r != null ? r.info.packageName : null;
   6512         }
   6513     }
   6514 
   6515     @Override
   6516     public ComponentName getCallingActivity(IBinder token) {
   6517         synchronized (this) {
   6518             ActivityRecord r = getCallingRecordLocked(token);
   6519             return r != null ? r.intent.getComponent() : null;
   6520         }
   6521     }
   6522 
   6523     private ActivityRecord getCallingRecordLocked(IBinder token) {
   6524         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6525         if (r == null) {
   6526             return null;
   6527         }
   6528         return r.resultTo;
   6529     }
   6530 
   6531     @Override
   6532     public ComponentName getActivityClassForToken(IBinder token) {
   6533         synchronized(this) {
   6534             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6535             if (r == null) {
   6536                 return null;
   6537             }
   6538             return r.intent.getComponent();
   6539         }
   6540     }
   6541 
   6542     @Override
   6543     public String getPackageForToken(IBinder token) {
   6544         synchronized(this) {
   6545             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   6546             if (r == null) {
   6547                 return null;
   6548             }
   6549             return r.packageName;
   6550         }
   6551     }
   6552 
   6553     @Override
   6554     public IIntentSender getIntentSender(int type,
   6555             String packageName, IBinder token, String resultWho,
   6556             int requestCode, Intent[] intents, String[] resolvedTypes,
   6557             int flags, Bundle options, int userId) {
   6558         enforceNotIsolatedCaller("getIntentSender");
   6559         // Refuse possible leaked file descriptors
   6560         if (intents != null) {
   6561             if (intents.length < 1) {
   6562                 throw new IllegalArgumentException("Intents array length must be >= 1");
   6563             }
   6564             for (int i=0; i<intents.length; i++) {
   6565                 Intent intent = intents[i];
   6566                 if (intent != null) {
   6567                     if (intent.hasFileDescriptors()) {
   6568                         throw new IllegalArgumentException("File descriptors passed in Intent");
   6569                     }
   6570                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   6571                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   6572                         throw new IllegalArgumentException(
   6573                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   6574                     }
   6575                     intents[i] = new Intent(intent);
   6576                 }
   6577             }
   6578             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   6579                 throw new IllegalArgumentException(
   6580                         "Intent array length does not match resolvedTypes length");
   6581             }
   6582         }
   6583         if (options != null) {
   6584             if (options.hasFileDescriptors()) {
   6585                 throw new IllegalArgumentException("File descriptors passed in options");
   6586             }
   6587         }
   6588 
   6589         synchronized(this) {
   6590             int callingUid = Binder.getCallingUid();
   6591             int origUserId = userId;
   6592             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   6593                     type == ActivityManager.INTENT_SENDER_BROADCAST,
   6594                     ALLOW_NON_FULL, "getIntentSender", null);
   6595             if (origUserId == UserHandle.USER_CURRENT) {
   6596                 // We don't want to evaluate this until the pending intent is
   6597                 // actually executed.  However, we do want to always do the
   6598                 // security checking for it above.
   6599                 userId = UserHandle.USER_CURRENT;
   6600             }
   6601             try {
   6602                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   6603                     int uid = AppGlobals.getPackageManager()
   6604                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   6605                     if (!UserHandle.isSameApp(callingUid, uid)) {
   6606                         String msg = "Permission Denial: getIntentSender() from pid="
   6607                             + Binder.getCallingPid()
   6608                             + ", uid=" + Binder.getCallingUid()
   6609                             + ", (need uid=" + uid + ")"
   6610                             + " is not allowed to send as package " + packageName;
   6611                         Slog.w(TAG, msg);
   6612                         throw new SecurityException(msg);
   6613                     }
   6614                 }
   6615 
   6616                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   6617                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   6618 
   6619             } catch (RemoteException e) {
   6620                 throw new SecurityException(e);
   6621             }
   6622         }
   6623     }
   6624 
   6625     IIntentSender getIntentSenderLocked(int type, String packageName,
   6626             int callingUid, int userId, IBinder token, String resultWho,
   6627             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   6628             Bundle options) {
   6629         if (DEBUG_MU)
   6630             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   6631         ActivityRecord activity = null;
   6632         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6633             activity = ActivityRecord.isInStackLocked(token);
   6634             if (activity == null) {
   6635                 return null;
   6636             }
   6637             if (activity.finishing) {
   6638                 return null;
   6639             }
   6640         }
   6641 
   6642         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   6643         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   6644         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   6645         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   6646                 |PendingIntent.FLAG_UPDATE_CURRENT);
   6647 
   6648         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   6649                 type, packageName, activity, resultWho,
   6650                 requestCode, intents, resolvedTypes, flags, options, userId);
   6651         WeakReference<PendingIntentRecord> ref;
   6652         ref = mIntentSenderRecords.get(key);
   6653         PendingIntentRecord rec = ref != null ? ref.get() : null;
   6654         if (rec != null) {
   6655             if (!cancelCurrent) {
   6656                 if (updateCurrent) {
   6657                     if (rec.key.requestIntent != null) {
   6658                         rec.key.requestIntent.replaceExtras(intents != null ?
   6659                                 intents[intents.length - 1] : null);
   6660                     }
   6661                     if (intents != null) {
   6662                         intents[intents.length-1] = rec.key.requestIntent;
   6663                         rec.key.allIntents = intents;
   6664                         rec.key.allResolvedTypes = resolvedTypes;
   6665                     } else {
   6666                         rec.key.allIntents = null;
   6667                         rec.key.allResolvedTypes = null;
   6668                     }
   6669                 }
   6670                 return rec;
   6671             }
   6672             rec.canceled = true;
   6673             mIntentSenderRecords.remove(key);
   6674         }
   6675         if (noCreate) {
   6676             return rec;
   6677         }
   6678         rec = new PendingIntentRecord(this, key, callingUid);
   6679         mIntentSenderRecords.put(key, rec.ref);
   6680         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   6681             if (activity.pendingResults == null) {
   6682                 activity.pendingResults
   6683                         = new HashSet<WeakReference<PendingIntentRecord>>();
   6684             }
   6685             activity.pendingResults.add(rec.ref);
   6686         }
   6687         return rec;
   6688     }
   6689 
   6690     @Override
   6691     public void cancelIntentSender(IIntentSender sender) {
   6692         if (!(sender instanceof PendingIntentRecord)) {
   6693             return;
   6694         }
   6695         synchronized(this) {
   6696             PendingIntentRecord rec = (PendingIntentRecord)sender;
   6697             try {
   6698                 int uid = AppGlobals.getPackageManager()
   6699                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   6700                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   6701                     String msg = "Permission Denial: cancelIntentSender() from pid="
   6702                         + Binder.getCallingPid()
   6703                         + ", uid=" + Binder.getCallingUid()
   6704                         + " is not allowed to cancel packges "
   6705                         + rec.key.packageName;
   6706                     Slog.w(TAG, msg);
   6707                     throw new SecurityException(msg);
   6708                 }
   6709             } catch (RemoteException e) {
   6710                 throw new SecurityException(e);
   6711             }
   6712             cancelIntentSenderLocked(rec, true);
   6713         }
   6714     }
   6715 
   6716     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   6717         rec.canceled = true;
   6718         mIntentSenderRecords.remove(rec.key);
   6719         if (cleanActivity && rec.key.activity != null) {
   6720             rec.key.activity.pendingResults.remove(rec.ref);
   6721         }
   6722     }
   6723 
   6724     @Override
   6725     public String getPackageForIntentSender(IIntentSender pendingResult) {
   6726         if (!(pendingResult instanceof PendingIntentRecord)) {
   6727             return null;
   6728         }
   6729         try {
   6730             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6731             return res.key.packageName;
   6732         } catch (ClassCastException e) {
   6733         }
   6734         return null;
   6735     }
   6736 
   6737     @Override
   6738     public int getUidForIntentSender(IIntentSender sender) {
   6739         if (sender instanceof PendingIntentRecord) {
   6740             try {
   6741                 PendingIntentRecord res = (PendingIntentRecord)sender;
   6742                 return res.uid;
   6743             } catch (ClassCastException e) {
   6744             }
   6745         }
   6746         return -1;
   6747     }
   6748 
   6749     @Override
   6750     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   6751         if (!(pendingResult instanceof PendingIntentRecord)) {
   6752             return false;
   6753         }
   6754         try {
   6755             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6756             if (res.key.allIntents == null) {
   6757                 return false;
   6758             }
   6759             for (int i=0; i<res.key.allIntents.length; i++) {
   6760                 Intent intent = res.key.allIntents[i];
   6761                 if (intent.getPackage() != null && intent.getComponent() != null) {
   6762                     return false;
   6763                 }
   6764             }
   6765             return true;
   6766         } catch (ClassCastException e) {
   6767         }
   6768         return false;
   6769     }
   6770 
   6771     @Override
   6772     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   6773         if (!(pendingResult instanceof PendingIntentRecord)) {
   6774             return false;
   6775         }
   6776         try {
   6777             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6778             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   6779                 return true;
   6780             }
   6781             return false;
   6782         } catch (ClassCastException e) {
   6783         }
   6784         return false;
   6785     }
   6786 
   6787     @Override
   6788     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   6789         if (!(pendingResult instanceof PendingIntentRecord)) {
   6790             return null;
   6791         }
   6792         try {
   6793             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6794             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   6795         } catch (ClassCastException e) {
   6796         }
   6797         return null;
   6798     }
   6799 
   6800     @Override
   6801     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
   6802         if (!(pendingResult instanceof PendingIntentRecord)) {
   6803             return null;
   6804         }
   6805         try {
   6806             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   6807             Intent intent = res.key.requestIntent;
   6808             if (intent != null) {
   6809                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
   6810                         || res.lastTagPrefix.equals(prefix))) {
   6811                     return res.lastTag;
   6812                 }
   6813                 res.lastTagPrefix = prefix;
   6814                 StringBuilder sb = new StringBuilder(128);
   6815                 if (prefix != null) {
   6816                     sb.append(prefix);
   6817                 }
   6818                 if (intent.getAction() != null) {
   6819                     sb.append(intent.getAction());
   6820                 } else if (intent.getComponent() != null) {
   6821                     intent.getComponent().appendShortString(sb);
   6822                 } else {
   6823                     sb.append("?");
   6824                 }
   6825                 return res.lastTag = sb.toString();
   6826             }
   6827         } catch (ClassCastException e) {
   6828         }
   6829         return null;
   6830     }
   6831 
   6832     @Override
   6833     public void setProcessLimit(int max) {
   6834         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6835                 "setProcessLimit()");
   6836         synchronized (this) {
   6837             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   6838             mProcessLimitOverride = max;
   6839         }
   6840         trimApplications();
   6841     }
   6842 
   6843     @Override
   6844     public int getProcessLimit() {
   6845         synchronized (this) {
   6846             return mProcessLimitOverride;
   6847         }
   6848     }
   6849 
   6850     void foregroundTokenDied(ForegroundToken token) {
   6851         synchronized (ActivityManagerService.this) {
   6852             synchronized (mPidsSelfLocked) {
   6853                 ForegroundToken cur
   6854                     = mForegroundProcesses.get(token.pid);
   6855                 if (cur != token) {
   6856                     return;
   6857                 }
   6858                 mForegroundProcesses.remove(token.pid);
   6859                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   6860                 if (pr == null) {
   6861                     return;
   6862                 }
   6863                 pr.forcingToForeground = null;
   6864                 updateProcessForegroundLocked(pr, false, false);
   6865             }
   6866             updateOomAdjLocked();
   6867         }
   6868     }
   6869 
   6870     @Override
   6871     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   6872         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   6873                 "setProcessForeground()");
   6874         synchronized(this) {
   6875             boolean changed = false;
   6876 
   6877             synchronized (mPidsSelfLocked) {
   6878                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   6879                 if (pr == null && isForeground) {
   6880                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   6881                     return;
   6882                 }
   6883                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   6884                 if (oldToken != null) {
   6885                     oldToken.token.unlinkToDeath(oldToken, 0);
   6886                     mForegroundProcesses.remove(pid);
   6887                     if (pr != null) {
   6888                         pr.forcingToForeground = null;
   6889                     }
   6890                     changed = true;
   6891                 }
   6892                 if (isForeground && token != null) {
   6893                     ForegroundToken newToken = new ForegroundToken() {
   6894                         @Override
   6895                         public void binderDied() {
   6896                             foregroundTokenDied(this);
   6897                         }
   6898                     };
   6899                     newToken.pid = pid;
   6900                     newToken.token = token;
   6901                     try {
   6902                         token.linkToDeath(newToken, 0);
   6903                         mForegroundProcesses.put(pid, newToken);
   6904                         pr.forcingToForeground = token;
   6905                         changed = true;
   6906                     } catch (RemoteException e) {
   6907                         // If the process died while doing this, we will later
   6908                         // do the cleanup with the process death link.
   6909                     }
   6910                 }
   6911             }
   6912 
   6913             if (changed) {
   6914                 updateOomAdjLocked();
   6915             }
   6916         }
   6917     }
   6918 
   6919     // =========================================================
   6920     // PERMISSIONS
   6921     // =========================================================
   6922 
   6923     static class PermissionController extends IPermissionController.Stub {
   6924         ActivityManagerService mActivityManagerService;
   6925         PermissionController(ActivityManagerService activityManagerService) {
   6926             mActivityManagerService = activityManagerService;
   6927         }
   6928 
   6929         @Override
   6930         public boolean checkPermission(String permission, int pid, int uid) {
   6931             return mActivityManagerService.checkPermission(permission, pid,
   6932                     uid) == PackageManager.PERMISSION_GRANTED;
   6933         }
   6934     }
   6935 
   6936     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   6937         @Override
   6938         public int checkComponentPermission(String permission, int pid, int uid,
   6939                 int owningUid, boolean exported) {
   6940             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   6941                     owningUid, exported);
   6942         }
   6943 
   6944         @Override
   6945         public Object getAMSLock() {
   6946             return ActivityManagerService.this;
   6947         }
   6948     }
   6949 
   6950     /**
   6951      * This can be called with or without the global lock held.
   6952      */
   6953     int checkComponentPermission(String permission, int pid, int uid,
   6954             int owningUid, boolean exported) {
   6955         // We might be performing an operation on behalf of an indirect binder
   6956         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   6957         // client identity accordingly before proceeding.
   6958         Identity tlsIdentity = sCallerIdentity.get();
   6959         if (tlsIdentity != null) {
   6960             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   6961                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   6962             uid = tlsIdentity.uid;
   6963             pid = tlsIdentity.pid;
   6964         }
   6965 
   6966         if (pid == MY_PID) {
   6967             return PackageManager.PERMISSION_GRANTED;
   6968         }
   6969 
   6970         return ActivityManager.checkComponentPermission(permission, uid,
   6971                 owningUid, exported);
   6972     }
   6973 
   6974     /**
   6975      * As the only public entry point for permissions checking, this method
   6976      * can enforce the semantic that requesting a check on a null global
   6977      * permission is automatically denied.  (Internally a null permission
   6978      * string is used when calling {@link #checkComponentPermission} in cases
   6979      * when only uid-based security is needed.)
   6980      *
   6981      * This can be called with or without the global lock held.
   6982      */
   6983     @Override
   6984     public int checkPermission(String permission, int pid, int uid) {
   6985         if (permission == null) {
   6986             return PackageManager.PERMISSION_DENIED;
   6987         }
   6988         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   6989     }
   6990 
   6991     /**
   6992      * Binder IPC calls go through the public entry point.
   6993      * This can be called with or without the global lock held.
   6994      */
   6995     int checkCallingPermission(String permission) {
   6996         return checkPermission(permission,
   6997                 Binder.getCallingPid(),
   6998                 UserHandle.getAppId(Binder.getCallingUid()));
   6999     }
   7000 
   7001     /**
   7002      * This can be called with or without the global lock held.
   7003      */
   7004     void enforceCallingPermission(String permission, String func) {
   7005         if (checkCallingPermission(permission)
   7006                 == PackageManager.PERMISSION_GRANTED) {
   7007             return;
   7008         }
   7009 
   7010         String msg = "Permission Denial: " + func + " from pid="
   7011                 + Binder.getCallingPid()
   7012                 + ", uid=" + Binder.getCallingUid()
   7013                 + " requires " + permission;
   7014         Slog.w(TAG, msg);
   7015         throw new SecurityException(msg);
   7016     }
   7017 
   7018     /**
   7019      * Determine if UID is holding permissions required to access {@link Uri} in
   7020      * the given {@link ProviderInfo}. Final permission checking is always done
   7021      * in {@link ContentProvider}.
   7022      */
   7023     private final boolean checkHoldingPermissionsLocked(
   7024             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
   7025         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7026                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
   7027         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
   7028             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
   7029                     != PERMISSION_GRANTED) {
   7030                 return false;
   7031             }
   7032         }
   7033         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
   7034     }
   7035 
   7036     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
   7037             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
   7038         if (pi.applicationInfo.uid == uid) {
   7039             return true;
   7040         } else if (!pi.exported) {
   7041             return false;
   7042         }
   7043 
   7044         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   7045         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   7046         try {
   7047             // check if target holds top-level <provider> permissions
   7048             if (!readMet && pi.readPermission != null && considerUidPermissions
   7049                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   7050                 readMet = true;
   7051             }
   7052             if (!writeMet && pi.writePermission != null && considerUidPermissions
   7053                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   7054                 writeMet = true;
   7055             }
   7056 
   7057             // track if unprotected read/write is allowed; any denied
   7058             // <path-permission> below removes this ability
   7059             boolean allowDefaultRead = pi.readPermission == null;
   7060             boolean allowDefaultWrite = pi.writePermission == null;
   7061 
   7062             // check if target holds any <path-permission> that match uri
   7063             final PathPermission[] pps = pi.pathPermissions;
   7064             if (pps != null) {
   7065                 final String path = grantUri.uri.getPath();
   7066                 int i = pps.length;
   7067                 while (i > 0 && (!readMet || !writeMet)) {
   7068                     i--;
   7069                     PathPermission pp = pps[i];
   7070                     if (pp.match(path)) {
   7071                         if (!readMet) {
   7072                             final String pprperm = pp.getReadPermission();
   7073                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   7074                                     + pprperm + " for " + pp.getPath()
   7075                                     + ": match=" + pp.match(path)
   7076                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   7077                             if (pprperm != null) {
   7078                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
   7079                                         == PERMISSION_GRANTED) {
   7080                                     readMet = true;
   7081                                 } else {
   7082                                     allowDefaultRead = false;
   7083                                 }
   7084                             }
   7085                         }
   7086                         if (!writeMet) {
   7087                             final String ppwperm = pp.getWritePermission();
   7088                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   7089                                     + ppwperm + " for " + pp.getPath()
   7090                                     + ": match=" + pp.match(path)
   7091                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   7092                             if (ppwperm != null) {
   7093                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
   7094                                         == PERMISSION_GRANTED) {
   7095                                     writeMet = true;
   7096                                 } else {
   7097                                     allowDefaultWrite = false;
   7098                                 }
   7099                             }
   7100                         }
   7101                     }
   7102                 }
   7103             }
   7104 
   7105             // grant unprotected <provider> read/write, if not blocked by
   7106             // <path-permission> above
   7107             if (allowDefaultRead) readMet = true;
   7108             if (allowDefaultWrite) writeMet = true;
   7109 
   7110         } catch (RemoteException e) {
   7111             return false;
   7112         }
   7113 
   7114         return readMet && writeMet;
   7115     }
   7116 
   7117     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
   7118         ProviderInfo pi = null;
   7119         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   7120         if (cpr != null) {
   7121             pi = cpr.info;
   7122         } else {
   7123             try {
   7124                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   7125                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
   7126             } catch (RemoteException ex) {
   7127             }
   7128         }
   7129         return pi;
   7130     }
   7131 
   7132     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
   7133         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7134         if (targetUris != null) {
   7135             return targetUris.get(grantUri);
   7136         }
   7137         return null;
   7138     }
   7139 
   7140     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
   7141             String targetPkg, int targetUid, GrantUri grantUri) {
   7142         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   7143         if (targetUris == null) {
   7144             targetUris = Maps.newArrayMap();
   7145             mGrantedUriPermissions.put(targetUid, targetUris);
   7146         }
   7147 
   7148         UriPermission perm = targetUris.get(grantUri);
   7149         if (perm == null) {
   7150             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
   7151             targetUris.put(grantUri, perm);
   7152         }
   7153 
   7154         return perm;
   7155     }
   7156 
   7157     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
   7158             final int modeFlags) {
   7159         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   7160         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   7161                 : UriPermission.STRENGTH_OWNED;
   7162 
   7163         // Root gets to do everything.
   7164         if (uid == 0) {
   7165             return true;
   7166         }
   7167 
   7168         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   7169         if (perms == null) return false;
   7170 
   7171         // First look for exact match
   7172         final UriPermission exactPerm = perms.get(grantUri);
   7173         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
   7174             return true;
   7175         }
   7176 
   7177         // No exact match, look for prefixes
   7178         final int N = perms.size();
   7179         for (int i = 0; i < N; i++) {
   7180             final UriPermission perm = perms.valueAt(i);
   7181             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
   7182                     && perm.getStrength(modeFlags) >= minStrength) {
   7183                 return true;
   7184             }
   7185         }
   7186 
   7187         return false;
   7188     }
   7189 
   7190     /**
   7191      * @param uri This uri must NOT contain an embedded userId.
   7192      * @param userId The userId in which the uri is to be resolved.
   7193      */
   7194     @Override
   7195     public int checkUriPermission(Uri uri, int pid, int uid,
   7196             final int modeFlags, int userId) {
   7197         enforceNotIsolatedCaller("checkUriPermission");
   7198 
   7199         // Another redirected-binder-call permissions check as in
   7200         // {@link checkComponentPermission}.
   7201         Identity tlsIdentity = sCallerIdentity.get();
   7202         if (tlsIdentity != null) {
   7203             uid = tlsIdentity.uid;
   7204             pid = tlsIdentity.pid;
   7205         }
   7206 
   7207         // Our own process gets to do everything.
   7208         if (pid == MY_PID) {
   7209             return PackageManager.PERMISSION_GRANTED;
   7210         }
   7211         synchronized (this) {
   7212             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
   7213                     ? PackageManager.PERMISSION_GRANTED
   7214                     : PackageManager.PERMISSION_DENIED;
   7215         }
   7216     }
   7217 
   7218     /**
   7219      * Check if the targetPkg can be granted permission to access uri by
   7220      * the callingUid using the given modeFlags.  Throws a security exception
   7221      * if callingUid is not allowed to do this.  Returns the uid of the target
   7222      * if the URI permission grant should be performed; returns -1 if it is not
   7223      * needed (for example targetPkg already has permission to access the URI).
   7224      * If you already know the uid of the target, you can supply it in
   7225      * lastTargetUid else set that to -1.
   7226      */
   7227     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7228             final int modeFlags, int lastTargetUid) {
   7229         if (!Intent.isAccessUriMode(modeFlags)) {
   7230             return -1;
   7231         }
   7232 
   7233         if (targetPkg != null) {
   7234             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7235                     "Checking grant " + targetPkg + " permission to " + grantUri);
   7236         }
   7237 
   7238         final IPackageManager pm = AppGlobals.getPackageManager();
   7239 
   7240         // If this is not a content: uri, we can't do anything with it.
   7241         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
   7242             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7243                     "Can't grant URI permission for non-content URI: " + grantUri);
   7244             return -1;
   7245         }
   7246 
   7247         final String authority = grantUri.uri.getAuthority();
   7248         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7249         if (pi == null) {
   7250             Slog.w(TAG, "No content provider found for permission check: " +
   7251                     grantUri.uri.toSafeString());
   7252             return -1;
   7253         }
   7254 
   7255         int targetUid = lastTargetUid;
   7256         if (targetUid < 0 && targetPkg != null) {
   7257             try {
   7258                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   7259                 if (targetUid < 0) {
   7260                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7261                             "Can't grant URI permission no uid for: " + targetPkg);
   7262                     return -1;
   7263                 }
   7264             } catch (RemoteException ex) {
   7265                 return -1;
   7266             }
   7267         }
   7268 
   7269         if (targetUid >= 0) {
   7270             // First...  does the target actually need this permission?
   7271             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
   7272                 // No need to grant the target this permission.
   7273                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7274                         "Target " + targetPkg + " already has full permission to " + grantUri);
   7275                 return -1;
   7276             }
   7277         } else {
   7278             // First...  there is no target package, so can anyone access it?
   7279             boolean allowed = pi.exported;
   7280             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   7281                 if (pi.readPermission != null) {
   7282                     allowed = false;
   7283                 }
   7284             }
   7285             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   7286                 if (pi.writePermission != null) {
   7287                     allowed = false;
   7288                 }
   7289             }
   7290             if (allowed) {
   7291                 return -1;
   7292             }
   7293         }
   7294 
   7295         /* There is a special cross user grant if:
   7296          * - The target is on another user.
   7297          * - Apps on the current user can access the uri without any uid permissions.
   7298          * In this case, we grant a uri permission, even if the ContentProvider does not normally
   7299          * grant uri permissions.
   7300          */
   7301         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
   7302                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
   7303                 modeFlags, false /*without considering the uid permissions*/);
   7304 
   7305         // Second...  is the provider allowing granting of URI permissions?
   7306         if (!specialCrossUserGrant) {
   7307             if (!pi.grantUriPermissions) {
   7308                 throw new SecurityException("Provider " + pi.packageName
   7309                         + "/" + pi.name
   7310                         + " does not allow granting of Uri permissions (uri "
   7311                         + grantUri + ")");
   7312             }
   7313             if (pi.uriPermissionPatterns != null) {
   7314                 final int N = pi.uriPermissionPatterns.length;
   7315                 boolean allowed = false;
   7316                 for (int i=0; i<N; i++) {
   7317                     if (pi.uriPermissionPatterns[i] != null
   7318                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
   7319                         allowed = true;
   7320                         break;
   7321                     }
   7322                 }
   7323                 if (!allowed) {
   7324                     throw new SecurityException("Provider " + pi.packageName
   7325                             + "/" + pi.name
   7326                             + " does not allow granting of permission to path of Uri "
   7327                             + grantUri);
   7328                 }
   7329             }
   7330         }
   7331 
   7332         // Third...  does the caller itself have permission to access
   7333         // this uri?
   7334         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
   7335             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7336                 // Require they hold a strong enough Uri permission
   7337                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
   7338                     throw new SecurityException("Uid " + callingUid
   7339                             + " does not have permission to uri " + grantUri);
   7340                 }
   7341             }
   7342         }
   7343         return targetUid;
   7344     }
   7345 
   7346     /**
   7347      * @param uri This uri must NOT contain an embedded userId.
   7348      * @param userId The userId in which the uri is to be resolved.
   7349      */
   7350     @Override
   7351     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
   7352             final int modeFlags, int userId) {
   7353         enforceNotIsolatedCaller("checkGrantUriPermission");
   7354         synchronized(this) {
   7355             return checkGrantUriPermissionLocked(callingUid, targetPkg,
   7356                     new GrantUri(userId, uri, false), modeFlags, -1);
   7357         }
   7358     }
   7359 
   7360     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
   7361             final int modeFlags, UriPermissionOwner owner) {
   7362         if (!Intent.isAccessUriMode(modeFlags)) {
   7363             return;
   7364         }
   7365 
   7366         // So here we are: the caller has the assumed permission
   7367         // to the uri, and the target doesn't.  Let's now give this to
   7368         // the target.
   7369 
   7370         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7371                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
   7372 
   7373         final String authority = grantUri.uri.getAuthority();
   7374         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7375         if (pi == null) {
   7376             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
   7377             return;
   7378         }
   7379 
   7380         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
   7381             grantUri.prefix = true;
   7382         }
   7383         final UriPermission perm = findOrCreateUriPermissionLocked(
   7384                 pi.packageName, targetPkg, targetUid, grantUri);
   7385         perm.grantModes(modeFlags, owner);
   7386     }
   7387 
   7388     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
   7389             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
   7390         if (targetPkg == null) {
   7391             throw new NullPointerException("targetPkg");
   7392         }
   7393         int targetUid;
   7394         final IPackageManager pm = AppGlobals.getPackageManager();
   7395         try {
   7396             targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7397         } catch (RemoteException ex) {
   7398             return;
   7399         }
   7400 
   7401         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
   7402                 targetUid);
   7403         if (targetUid < 0) {
   7404             return;
   7405         }
   7406 
   7407         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
   7408                 owner);
   7409     }
   7410 
   7411     static class NeededUriGrants extends ArrayList<GrantUri> {
   7412         final String targetPkg;
   7413         final int targetUid;
   7414         final int flags;
   7415 
   7416         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   7417             this.targetPkg = targetPkg;
   7418             this.targetUid = targetUid;
   7419             this.flags = flags;
   7420         }
   7421     }
   7422 
   7423     /**
   7424      * Like checkGrantUriPermissionLocked, but takes an Intent.
   7425      */
   7426     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   7427             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
   7428         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7429                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   7430                 + " clip=" + (intent != null ? intent.getClipData() : null)
   7431                 + " from " + intent + "; flags=0x"
   7432                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   7433 
   7434         if (targetPkg == null) {
   7435             throw new NullPointerException("targetPkg");
   7436         }
   7437 
   7438         if (intent == null) {
   7439             return null;
   7440         }
   7441         Uri data = intent.getData();
   7442         ClipData clip = intent.getClipData();
   7443         if (data == null && clip == null) {
   7444             return null;
   7445         }
   7446         // Default userId for uris in the intent (if they don't specify it themselves)
   7447         int contentUserHint = intent.getContentUserHint();
   7448         if (contentUserHint == UserHandle.USER_CURRENT) {
   7449             contentUserHint = UserHandle.getUserId(callingUid);
   7450         }
   7451         final IPackageManager pm = AppGlobals.getPackageManager();
   7452         int targetUid;
   7453         if (needed != null) {
   7454             targetUid = needed.targetUid;
   7455         } else {
   7456             try {
   7457                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
   7458             } catch (RemoteException ex) {
   7459                 return null;
   7460             }
   7461             if (targetUid < 0) {
   7462                 if (DEBUG_URI_PERMISSION) {
   7463                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
   7464                             + " on user " + targetUserId);
   7465                 }
   7466                 return null;
   7467             }
   7468         }
   7469         if (data != null) {
   7470             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
   7471             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7472                     targetUid);
   7473             if (targetUid > 0) {
   7474                 if (needed == null) {
   7475                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7476                 }
   7477                 needed.add(grantUri);
   7478             }
   7479         }
   7480         if (clip != null) {
   7481             for (int i=0; i<clip.getItemCount(); i++) {
   7482                 Uri uri = clip.getItemAt(i).getUri();
   7483                 if (uri != null) {
   7484                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
   7485                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
   7486                             targetUid);
   7487                     if (targetUid > 0) {
   7488                         if (needed == null) {
   7489                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   7490                         }
   7491                         needed.add(grantUri);
   7492                     }
   7493                 } else {
   7494                     Intent clipIntent = clip.getItemAt(i).getIntent();
   7495                     if (clipIntent != null) {
   7496                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   7497                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
   7498                         if (newNeeded != null) {
   7499                             needed = newNeeded;
   7500                         }
   7501                     }
   7502                 }
   7503             }
   7504         }
   7505 
   7506         return needed;
   7507     }
   7508 
   7509     /**
   7510      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   7511      */
   7512     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   7513             UriPermissionOwner owner) {
   7514         if (needed != null) {
   7515             for (int i=0; i<needed.size(); i++) {
   7516                 GrantUri grantUri = needed.get(i);
   7517                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   7518                         grantUri, needed.flags, owner);
   7519             }
   7520         }
   7521     }
   7522 
   7523     void grantUriPermissionFromIntentLocked(int callingUid,
   7524             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
   7525         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   7526                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
   7527         if (needed == null) {
   7528             return;
   7529         }
   7530 
   7531         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   7532     }
   7533 
   7534     /**
   7535      * @param uri This uri must NOT contain an embedded userId.
   7536      * @param userId The userId in which the uri is to be resolved.
   7537      */
   7538     @Override
   7539     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
   7540             final int modeFlags, int userId) {
   7541         enforceNotIsolatedCaller("grantUriPermission");
   7542         GrantUri grantUri = new GrantUri(userId, uri, false);
   7543         synchronized(this) {
   7544             final ProcessRecord r = getRecordForAppLocked(caller);
   7545             if (r == null) {
   7546                 throw new SecurityException("Unable to find app for caller "
   7547                         + caller
   7548                         + " when granting permission to uri " + grantUri);
   7549             }
   7550             if (targetPkg == null) {
   7551                 throw new IllegalArgumentException("null target");
   7552             }
   7553             if (grantUri == null) {
   7554                 throw new IllegalArgumentException("null uri");
   7555             }
   7556 
   7557             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
   7558                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   7559                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
   7560                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
   7561 
   7562             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
   7563                     UserHandle.getUserId(r.uid));
   7564         }
   7565     }
   7566 
   7567     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   7568         if (perm.modeFlags == 0) {
   7569             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   7570                     perm.targetUid);
   7571             if (perms != null) {
   7572                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   7573                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   7574 
   7575                 perms.remove(perm.uri);
   7576                 if (perms.isEmpty()) {
   7577                     mGrantedUriPermissions.remove(perm.targetUid);
   7578                 }
   7579             }
   7580         }
   7581     }
   7582 
   7583     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
   7584         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
   7585 
   7586         final IPackageManager pm = AppGlobals.getPackageManager();
   7587         final String authority = grantUri.uri.getAuthority();
   7588         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
   7589         if (pi == null) {
   7590             Slog.w(TAG, "No content provider found for permission revoke: "
   7591                     + grantUri.toSafeString());
   7592             return;
   7593         }
   7594 
   7595         // Does the caller have this permission on the URI?
   7596         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
   7597             // If they don't have direct access to the URI, then revoke any
   7598             // ownerless URI permissions that have been granted to them.
   7599             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   7600             if (perms != null) {
   7601                 boolean persistChanged = false;
   7602                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7603                     final UriPermission perm = it.next();
   7604                     if (perm.uri.sourceUserId == grantUri.sourceUserId
   7605                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   7606                         if (DEBUG_URI_PERMISSION)
   7607                             Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
   7608                                     " permission to " + perm.uri);
   7609                         persistChanged |= perm.revokeModes(
   7610                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
   7611                         if (perm.modeFlags == 0) {
   7612                             it.remove();
   7613                         }
   7614                     }
   7615                 }
   7616                 if (perms.isEmpty()) {
   7617                     mGrantedUriPermissions.remove(callingUid);
   7618                 }
   7619                 if (persistChanged) {
   7620                     schedulePersistUriGrants();
   7621                 }
   7622             }
   7623             return;
   7624         }
   7625 
   7626         boolean persistChanged = false;
   7627 
   7628         // Go through all of the permissions and remove any that match.
   7629         int N = mGrantedUriPermissions.size();
   7630         for (int i = 0; i < N; i++) {
   7631             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7632             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7633 
   7634             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7635                 final UriPermission perm = it.next();
   7636                 if (perm.uri.sourceUserId == grantUri.sourceUserId
   7637                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
   7638                     if (DEBUG_URI_PERMISSION)
   7639                         Slog.v(TAG,
   7640                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
   7641                     persistChanged |= perm.revokeModes(
   7642                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7643                     if (perm.modeFlags == 0) {
   7644                         it.remove();
   7645                     }
   7646                 }
   7647             }
   7648 
   7649             if (perms.isEmpty()) {
   7650                 mGrantedUriPermissions.remove(targetUid);
   7651                 N--;
   7652                 i--;
   7653             }
   7654         }
   7655 
   7656         if (persistChanged) {
   7657             schedulePersistUriGrants();
   7658         }
   7659     }
   7660 
   7661     /**
   7662      * @param uri This uri must NOT contain an embedded userId.
   7663      * @param userId The userId in which the uri is to be resolved.
   7664      */
   7665     @Override
   7666     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
   7667             int userId) {
   7668         enforceNotIsolatedCaller("revokeUriPermission");
   7669         synchronized(this) {
   7670             final ProcessRecord r = getRecordForAppLocked(caller);
   7671             if (r == null) {
   7672                 throw new SecurityException("Unable to find app for caller "
   7673                         + caller
   7674                         + " when revoking permission to uri " + uri);
   7675             }
   7676             if (uri == null) {
   7677                 Slog.w(TAG, "revokeUriPermission: null uri");
   7678                 return;
   7679             }
   7680 
   7681             if (!Intent.isAccessUriMode(modeFlags)) {
   7682                 return;
   7683             }
   7684 
   7685             final IPackageManager pm = AppGlobals.getPackageManager();
   7686             final String authority = uri.getAuthority();
   7687             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
   7688             if (pi == null) {
   7689                 Slog.w(TAG, "No content provider found for permission revoke: "
   7690                         + uri.toSafeString());
   7691                 return;
   7692             }
   7693 
   7694             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
   7695         }
   7696     }
   7697 
   7698     /**
   7699      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   7700      * given package.
   7701      *
   7702      * @param packageName Package name to match, or {@code null} to apply to all
   7703      *            packages.
   7704      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   7705      *            to all users.
   7706      * @param persistable If persistable grants should be removed.
   7707      */
   7708     private void removeUriPermissionsForPackageLocked(
   7709             String packageName, int userHandle, boolean persistable) {
   7710         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   7711             throw new IllegalArgumentException("Must narrow by either package or user");
   7712         }
   7713 
   7714         boolean persistChanged = false;
   7715 
   7716         int N = mGrantedUriPermissions.size();
   7717         for (int i = 0; i < N; i++) {
   7718             final int targetUid = mGrantedUriPermissions.keyAt(i);
   7719             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7720 
   7721             // Only inspect grants matching user
   7722             if (userHandle == UserHandle.USER_ALL
   7723                     || userHandle == UserHandle.getUserId(targetUid)) {
   7724                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
   7725                     final UriPermission perm = it.next();
   7726 
   7727                     // Only inspect grants matching package
   7728                     if (packageName == null || perm.sourcePkg.equals(packageName)
   7729                             || perm.targetPkg.equals(packageName)) {
   7730                         persistChanged |= perm.revokeModes(persistable
   7731                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
   7732 
   7733                         // Only remove when no modes remain; any persisted grants
   7734                         // will keep this alive.
   7735                         if (perm.modeFlags == 0) {
   7736                             it.remove();
   7737                         }
   7738                     }
   7739                 }
   7740 
   7741                 if (perms.isEmpty()) {
   7742                     mGrantedUriPermissions.remove(targetUid);
   7743                     N--;
   7744                     i--;
   7745                 }
   7746             }
   7747         }
   7748 
   7749         if (persistChanged) {
   7750             schedulePersistUriGrants();
   7751         }
   7752     }
   7753 
   7754     @Override
   7755     public IBinder newUriPermissionOwner(String name) {
   7756         enforceNotIsolatedCaller("newUriPermissionOwner");
   7757         synchronized(this) {
   7758             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   7759             return owner.getExternalTokenLocked();
   7760         }
   7761     }
   7762 
   7763     /**
   7764      * @param uri This uri must NOT contain an embedded userId.
   7765      * @param sourceUserId The userId in which the uri is to be resolved.
   7766      * @param targetUserId The userId of the app that receives the grant.
   7767      */
   7768     @Override
   7769     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
   7770             final int modeFlags, int sourceUserId, int targetUserId) {
   7771         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   7772                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
   7773         synchronized(this) {
   7774             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7775             if (owner == null) {
   7776                 throw new IllegalArgumentException("Unknown owner: " + token);
   7777             }
   7778             if (fromUid != Binder.getCallingUid()) {
   7779                 if (Binder.getCallingUid() != Process.myUid()) {
   7780                     // Only system code can grant URI permissions on behalf
   7781                     // of other users.
   7782                     throw new SecurityException("nice try");
   7783                 }
   7784             }
   7785             if (targetPkg == null) {
   7786                 throw new IllegalArgumentException("null target");
   7787             }
   7788             if (uri == null) {
   7789                 throw new IllegalArgumentException("null uri");
   7790             }
   7791 
   7792             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
   7793                     modeFlags, owner, targetUserId);
   7794         }
   7795     }
   7796 
   7797     /**
   7798      * @param uri This uri must NOT contain an embedded userId.
   7799      * @param userId The userId in which the uri is to be resolved.
   7800      */
   7801     @Override
   7802     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
   7803         synchronized(this) {
   7804             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   7805             if (owner == null) {
   7806                 throw new IllegalArgumentException("Unknown owner: " + token);
   7807             }
   7808 
   7809             if (uri == null) {
   7810                 owner.removeUriPermissionsLocked(mode);
   7811             } else {
   7812                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
   7813             }
   7814         }
   7815     }
   7816 
   7817     private void schedulePersistUriGrants() {
   7818         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   7819             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   7820                     10 * DateUtils.SECOND_IN_MILLIS);
   7821         }
   7822     }
   7823 
   7824     private void writeGrantedUriPermissions() {
   7825         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
   7826 
   7827         // Snapshot permissions so we can persist without lock
   7828         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   7829         synchronized (this) {
   7830             final int size = mGrantedUriPermissions.size();
   7831             for (int i = 0; i < size; i++) {
   7832                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   7833                 for (UriPermission perm : perms.values()) {
   7834                     if (perm.persistedModeFlags != 0) {
   7835                         persist.add(perm.snapshot());
   7836                     }
   7837                 }
   7838             }
   7839         }
   7840 
   7841         FileOutputStream fos = null;
   7842         try {
   7843             fos = mGrantFile.startWrite();
   7844 
   7845             XmlSerializer out = new FastXmlSerializer();
   7846             out.setOutput(fos, "utf-8");
   7847             out.startDocument(null, true);
   7848             out.startTag(null, TAG_URI_GRANTS);
   7849             for (UriPermission.Snapshot perm : persist) {
   7850                 out.startTag(null, TAG_URI_GRANT);
   7851                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
   7852                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
   7853                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   7854                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   7855                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
   7856                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
   7857                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   7858                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   7859                 out.endTag(null, TAG_URI_GRANT);
   7860             }
   7861             out.endTag(null, TAG_URI_GRANTS);
   7862             out.endDocument();
   7863 
   7864             mGrantFile.finishWrite(fos);
   7865         } catch (IOException e) {
   7866             if (fos != null) {
   7867                 mGrantFile.failWrite(fos);
   7868             }
   7869         }
   7870     }
   7871 
   7872     private void readGrantedUriPermissionsLocked() {
   7873         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
   7874 
   7875         final long now = System.currentTimeMillis();
   7876 
   7877         FileInputStream fis = null;
   7878         try {
   7879             fis = mGrantFile.openRead();
   7880             final XmlPullParser in = Xml.newPullParser();
   7881             in.setInput(fis, null);
   7882 
   7883             int type;
   7884             while ((type = in.next()) != END_DOCUMENT) {
   7885                 final String tag = in.getName();
   7886                 if (type == START_TAG) {
   7887                     if (TAG_URI_GRANT.equals(tag)) {
   7888                         final int sourceUserId;
   7889                         final int targetUserId;
   7890                         final int userHandle = readIntAttribute(in,
   7891                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
   7892                         if (userHandle != UserHandle.USER_NULL) {
   7893                             // For backwards compatibility.
   7894                             sourceUserId = userHandle;
   7895                             targetUserId = userHandle;
   7896                         } else {
   7897                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
   7898                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
   7899                         }
   7900                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   7901                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   7902                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   7903                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
   7904                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   7905                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   7906 
   7907                         // Sanity check that provider still belongs to source package
   7908                         final ProviderInfo pi = getProviderInfoLocked(
   7909                                 uri.getAuthority(), sourceUserId);
   7910                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   7911                             int targetUid = -1;
   7912                             try {
   7913                                 targetUid = AppGlobals.getPackageManager()
   7914                                         .getPackageUid(targetPkg, targetUserId);
   7915                             } catch (RemoteException e) {
   7916                             }
   7917                             if (targetUid != -1) {
   7918                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   7919                                         sourcePkg, targetPkg, targetUid,
   7920                                         new GrantUri(sourceUserId, uri, prefix));
   7921                                 perm.initPersistedModes(modeFlags, createdTime);
   7922                             }
   7923                         } else {
   7924                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   7925                                     + " but instead found " + pi);
   7926                         }
   7927                     }
   7928                 }
   7929             }
   7930         } catch (FileNotFoundException e) {
   7931             // Missing grants is okay
   7932         } catch (IOException e) {
   7933             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7934         } catch (XmlPullParserException e) {
   7935             Slog.wtf(TAG, "Failed reading Uri grants", e);
   7936         } finally {
   7937             IoUtils.closeQuietly(fis);
   7938         }
   7939     }
   7940 
   7941     /**
   7942      * @param uri This uri must NOT contain an embedded userId.
   7943      * @param userId The userId in which the uri is to be resolved.
   7944      */
   7945     @Override
   7946     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7947         enforceNotIsolatedCaller("takePersistableUriPermission");
   7948 
   7949         Preconditions.checkFlagsArgument(modeFlags,
   7950                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7951 
   7952         synchronized (this) {
   7953             final int callingUid = Binder.getCallingUid();
   7954             boolean persistChanged = false;
   7955             GrantUri grantUri = new GrantUri(userId, uri, false);
   7956 
   7957             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   7958                     new GrantUri(userId, uri, false));
   7959             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   7960                     new GrantUri(userId, uri, true));
   7961 
   7962             final boolean exactValid = (exactPerm != null)
   7963                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
   7964             final boolean prefixValid = (prefixPerm != null)
   7965                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
   7966 
   7967             if (!(exactValid || prefixValid)) {
   7968                 throw new SecurityException("No persistable permission grants found for UID "
   7969                         + callingUid + " and Uri " + grantUri.toSafeString());
   7970             }
   7971 
   7972             if (exactValid) {
   7973                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
   7974             }
   7975             if (prefixValid) {
   7976                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
   7977             }
   7978 
   7979             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   7980 
   7981             if (persistChanged) {
   7982                 schedulePersistUriGrants();
   7983             }
   7984         }
   7985     }
   7986 
   7987     /**
   7988      * @param uri This uri must NOT contain an embedded userId.
   7989      * @param userId The userId in which the uri is to be resolved.
   7990      */
   7991     @Override
   7992     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
   7993         enforceNotIsolatedCaller("releasePersistableUriPermission");
   7994 
   7995         Preconditions.checkFlagsArgument(modeFlags,
   7996                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   7997 
   7998         synchronized (this) {
   7999             final int callingUid = Binder.getCallingUid();
   8000             boolean persistChanged = false;
   8001 
   8002             UriPermission exactPerm = findUriPermissionLocked(callingUid,
   8003                     new GrantUri(userId, uri, false));
   8004             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
   8005                     new GrantUri(userId, uri, true));
   8006             if (exactPerm == null && prefixPerm == null) {
   8007                 throw new SecurityException("No permission grants found for UID " + callingUid
   8008                         + " and Uri " + uri.toSafeString());
   8009             }
   8010 
   8011             if (exactPerm != null) {
   8012                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
   8013                 removeUriPermissionIfNeededLocked(exactPerm);
   8014             }
   8015             if (prefixPerm != null) {
   8016                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
   8017                 removeUriPermissionIfNeededLocked(prefixPerm);
   8018             }
   8019 
   8020             if (persistChanged) {
   8021                 schedulePersistUriGrants();
   8022             }
   8023         }
   8024     }
   8025 
   8026     /**
   8027      * Prune any older {@link UriPermission} for the given UID until outstanding
   8028      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   8029      *
   8030      * @return if any mutations occured that require persisting.
   8031      */
   8032     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   8033         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   8034         if (perms == null) return false;
   8035         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   8036 
   8037         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   8038         for (UriPermission perm : perms.values()) {
   8039             if (perm.persistedModeFlags != 0) {
   8040                 persisted.add(perm);
   8041             }
   8042         }
   8043 
   8044         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   8045         if (trimCount <= 0) return false;
   8046 
   8047         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   8048         for (int i = 0; i < trimCount; i++) {
   8049             final UriPermission perm = persisted.get(i);
   8050 
   8051             if (DEBUG_URI_PERMISSION) {
   8052                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
   8053             }
   8054 
   8055             perm.releasePersistableModes(~0);
   8056             removeUriPermissionIfNeededLocked(perm);
   8057         }
   8058 
   8059         return true;
   8060     }
   8061 
   8062     @Override
   8063     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   8064             String packageName, boolean incoming) {
   8065         enforceNotIsolatedCaller("getPersistedUriPermissions");
   8066         Preconditions.checkNotNull(packageName, "packageName");
   8067 
   8068         final int callingUid = Binder.getCallingUid();
   8069         final IPackageManager pm = AppGlobals.getPackageManager();
   8070         try {
   8071             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
   8072             if (packageUid != callingUid) {
   8073                 throw new SecurityException(
   8074                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   8075             }
   8076         } catch (RemoteException e) {
   8077             throw new SecurityException("Failed to verify package name ownership");
   8078         }
   8079 
   8080         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   8081         synchronized (this) {
   8082             if (incoming) {
   8083                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
   8084                         callingUid);
   8085                 if (perms == null) {
   8086                     Slog.w(TAG, "No permission grants found for " + packageName);
   8087                 } else {
   8088                     for (UriPermission perm : perms.values()) {
   8089                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   8090                             result.add(perm.buildPersistedPublicApiObject());
   8091                         }
   8092                     }
   8093                 }
   8094             } else {
   8095                 final int size = mGrantedUriPermissions.size();
   8096                 for (int i = 0; i < size; i++) {
   8097                     final ArrayMap<GrantUri, UriPermission> perms =
   8098                             mGrantedUriPermissions.valueAt(i);
   8099                     for (UriPermission perm : perms.values()) {
   8100                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   8101                             result.add(perm.buildPersistedPublicApiObject());
   8102                         }
   8103                     }
   8104                 }
   8105             }
   8106         }
   8107         return new ParceledListSlice<android.content.UriPermission>(result);
   8108     }
   8109 
   8110     @Override
   8111     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   8112         synchronized (this) {
   8113             ProcessRecord app =
   8114                 who != null ? getRecordForAppLocked(who) : null;
   8115             if (app == null) return;
   8116 
   8117             Message msg = Message.obtain();
   8118             msg.what = WAIT_FOR_DEBUGGER_MSG;
   8119             msg.obj = app;
   8120             msg.arg1 = waiting ? 1 : 0;
   8121             mHandler.sendMessage(msg);
   8122         }
   8123     }
   8124 
   8125     @Override
   8126     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   8127         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   8128         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   8129         outInfo.availMem = Process.getFreeMemory();
   8130         outInfo.totalMem = Process.getTotalMemory();
   8131         outInfo.threshold = homeAppMem;
   8132         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   8133         outInfo.hiddenAppThreshold = cachedAppMem;
   8134         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   8135                 ProcessList.SERVICE_ADJ);
   8136         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   8137                 ProcessList.VISIBLE_APP_ADJ);
   8138         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   8139                 ProcessList.FOREGROUND_APP_ADJ);
   8140     }
   8141 
   8142     // =========================================================
   8143     // TASK MANAGEMENT
   8144     // =========================================================
   8145 
   8146     @Override
   8147     public List<IAppTask> getAppTasks(String callingPackage) {
   8148         int callingUid = Binder.getCallingUid();
   8149         long ident = Binder.clearCallingIdentity();
   8150 
   8151         synchronized(this) {
   8152             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
   8153             try {
   8154                 if (localLOGV) Slog.v(TAG, "getAppTasks");
   8155 
   8156                 final int N = mRecentTasks.size();
   8157                 for (int i = 0; i < N; i++) {
   8158                     TaskRecord tr = mRecentTasks.get(i);
   8159                     // Skip tasks that do not match the caller.  We don't need to verify
   8160                     // callingPackage, because we are also limiting to callingUid and know
   8161                     // that will limit to the correct security sandbox.
   8162                     if (tr.effectiveUid != callingUid) {
   8163                         continue;
   8164                     }
   8165                     Intent intent = tr.getBaseIntent();
   8166                     if (intent == null ||
   8167                             !callingPackage.equals(intent.getComponent().getPackageName())) {
   8168                         continue;
   8169                     }
   8170                     ActivityManager.RecentTaskInfo taskInfo =
   8171                             createRecentTaskInfoFromTaskRecord(tr);
   8172                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
   8173                     list.add(taskImpl);
   8174                 }
   8175             } finally {
   8176                 Binder.restoreCallingIdentity(ident);
   8177             }
   8178             return list;
   8179         }
   8180     }
   8181 
   8182     @Override
   8183     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
   8184         final int callingUid = Binder.getCallingUid();
   8185         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   8186 
   8187         synchronized(this) {
   8188             if (localLOGV) Slog.v(
   8189                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
   8190 
   8191             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
   8192                     callingUid);
   8193 
   8194             // TODO: Improve with MRU list from all ActivityStacks.
   8195             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
   8196         }
   8197 
   8198         return list;
   8199     }
   8200 
   8201     TaskRecord getMostRecentTask() {
   8202         return mRecentTasks.get(0);
   8203     }
   8204 
   8205     /**
   8206      * Creates a new RecentTaskInfo from a TaskRecord.
   8207      */
   8208     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
   8209         // Update the task description to reflect any changes in the task stack
   8210         tr.updateTaskDescription();
   8211 
   8212         // Compose the recent task info
   8213         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
   8214         rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
   8215         rti.persistentId = tr.taskId;
   8216         rti.baseIntent = new Intent(tr.getBaseIntent());
   8217         rti.origActivity = tr.origActivity;
   8218         rti.description = tr.lastDescription;
   8219         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
   8220         rti.userId = tr.userId;
   8221         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
   8222         rti.firstActiveTime = tr.firstActiveTime;
   8223         rti.lastActiveTime = tr.lastActiveTime;
   8224         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
   8225         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
   8226         return rti;
   8227     }
   8228 
   8229     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
   8230         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
   8231                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
   8232         if (!allowed) {
   8233             if (checkPermission(android.Manifest.permission.GET_TASKS,
   8234                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
   8235                 // Temporary compatibility: some existing apps on the system image may
   8236                 // still be requesting the old permission and not switched to the new
   8237                 // one; if so, we'll still allow them full access.  This means we need
   8238                 // to see if they are holding the old permission and are a system app.
   8239                 try {
   8240                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
   8241                         allowed = true;
   8242                         Slog.w(TAG, caller + ": caller " + callingUid
   8243                                 + " is using old GET_TASKS but privileged; allowing");
   8244                     }
   8245                 } catch (RemoteException e) {
   8246                 }
   8247             }
   8248         }
   8249         if (!allowed) {
   8250             Slog.w(TAG, caller + ": caller " + callingUid
   8251                     + " does not hold GET_TASKS; limiting output");
   8252         }
   8253         return allowed;
   8254     }
   8255 
   8256     @Override
   8257     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
   8258         final int callingUid = Binder.getCallingUid();
   8259         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   8260                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
   8261 
   8262         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
   8263         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
   8264         synchronized (this) {
   8265             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
   8266                     callingUid);
   8267             final boolean detailed = checkCallingPermission(
   8268                     android.Manifest.permission.GET_DETAILED_TASKS)
   8269                     == PackageManager.PERMISSION_GRANTED;
   8270 
   8271             final int N = mRecentTasks.size();
   8272             ArrayList<ActivityManager.RecentTaskInfo> res
   8273                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   8274                             maxNum < N ? maxNum : N);
   8275 
   8276             final Set<Integer> includedUsers;
   8277             if (includeProfiles) {
   8278                 includedUsers = getProfileIdsLocked(userId);
   8279             } else {
   8280                 includedUsers = new HashSet<Integer>();
   8281             }
   8282             includedUsers.add(Integer.valueOf(userId));
   8283 
   8284             for (int i=0; i<N && maxNum > 0; i++) {
   8285                 TaskRecord tr = mRecentTasks.get(i);
   8286                 // Only add calling user or related users recent tasks
   8287                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
   8288                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
   8289                     continue;
   8290                 }
   8291 
   8292                 // Return the entry if desired by the caller.  We always return
   8293                 // the first entry, because callers always expect this to be the
   8294                 // foreground app.  We may filter others if the caller has
   8295                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   8296                 // we should exclude the entry.
   8297 
   8298                 if (i == 0
   8299                         || withExcluded
   8300                         || (tr.intent == null)
   8301                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
   8302                                 == 0)) {
   8303                     if (!allowed) {
   8304                         // If the caller doesn't have the GET_TASKS permission, then only
   8305                         // allow them to see a small subset of tasks -- their own and home.
   8306                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
   8307                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
   8308                             continue;
   8309                         }
   8310                     }
   8311                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
   8312                         if (tr.stack != null && tr.stack.isHomeStack()) {
   8313                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
   8314                             continue;
   8315                         }
   8316                     }
   8317                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
   8318                         // Don't include auto remove tasks that are finished or finishing.
   8319                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
   8320                                 + tr);
   8321                         continue;
   8322                     }
   8323                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
   8324                             && !tr.isAvailable) {
   8325                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
   8326                         continue;
   8327                     }
   8328 
   8329                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
   8330                     if (!detailed) {
   8331                         rti.baseIntent.replaceExtras((Bundle)null);
   8332                     }
   8333 
   8334                     res.add(rti);
   8335                     maxNum--;
   8336                 }
   8337             }
   8338             return res;
   8339         }
   8340     }
   8341 
   8342     private TaskRecord recentTaskForIdLocked(int id) {
   8343         final int N = mRecentTasks.size();
   8344             for (int i=0; i<N; i++) {
   8345                 TaskRecord tr = mRecentTasks.get(i);
   8346                 if (tr.taskId == id) {
   8347                     return tr;
   8348                 }
   8349             }
   8350             return null;
   8351     }
   8352 
   8353     @Override
   8354     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
   8355         synchronized (this) {
   8356             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   8357                     "getTaskThumbnail()");
   8358             TaskRecord tr = recentTaskForIdLocked(id);
   8359             if (tr != null) {
   8360                 return tr.getTaskThumbnailLocked();
   8361             }
   8362         }
   8363         return null;
   8364     }
   8365 
   8366     @Override
   8367     public int addAppTask(IBinder activityToken, Intent intent,
   8368             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
   8369         final int callingUid = Binder.getCallingUid();
   8370         final long callingIdent = Binder.clearCallingIdentity();
   8371 
   8372         try {
   8373             synchronized (this) {
   8374                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
   8375                 if (r == null) {
   8376                     throw new IllegalArgumentException("Activity does not exist; token="
   8377                             + activityToken);
   8378                 }
   8379                 ComponentName comp = intent.getComponent();
   8380                 if (comp == null) {
   8381                     throw new IllegalArgumentException("Intent " + intent
   8382                             + " must specify explicit component");
   8383                 }
   8384                 if (thumbnail.getWidth() != mThumbnailWidth
   8385                         || thumbnail.getHeight() != mThumbnailHeight) {
   8386                     throw new IllegalArgumentException("Bad thumbnail size: got "
   8387                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
   8388                             + mThumbnailWidth + "x" + mThumbnailHeight);
   8389                 }
   8390                 if (intent.getSelector() != null) {
   8391                     intent.setSelector(null);
   8392                 }
   8393                 if (intent.getSourceBounds() != null) {
   8394                     intent.setSourceBounds(null);
   8395                 }
   8396                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
   8397                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
   8398                         // The caller has added this as an auto-remove task...  that makes no
   8399                         // sense, so turn off auto-remove.
   8400                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
   8401                     }
   8402                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
   8403                     // Must be a new task.
   8404                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   8405                 }
   8406                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
   8407                     mLastAddedTaskActivity = null;
   8408                 }
   8409                 ActivityInfo ainfo = mLastAddedTaskActivity;
   8410                 if (ainfo == null) {
   8411                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
   8412                             comp, 0, UserHandle.getUserId(callingUid));
   8413                     if (ainfo.applicationInfo.uid != callingUid) {
   8414                         throw new SecurityException(
   8415                                 "Can't add task for another application: target uid="
   8416                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
   8417                     }
   8418                 }
   8419 
   8420                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
   8421                         intent, description);
   8422 
   8423                 int trimIdx = trimRecentsForTask(task, false);
   8424                 if (trimIdx >= 0) {
   8425                     // If this would have caused a trim, then we'll abort because that
   8426                     // means it would be added at the end of the list but then just removed.
   8427                     return -1;
   8428                 }
   8429 
   8430                 final int N = mRecentTasks.size();
   8431                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
   8432                     final TaskRecord tr = mRecentTasks.remove(N - 1);
   8433                     tr.removedFromRecents(mTaskPersister);
   8434                 }
   8435 
   8436                 task.inRecents = true;
   8437                 mRecentTasks.add(task);
   8438                 r.task.stack.addTask(task, false, false);
   8439 
   8440                 task.setLastThumbnail(thumbnail);
   8441                 task.freeLastThumbnail();
   8442 
   8443                 return task.taskId;
   8444             }
   8445         } finally {
   8446             Binder.restoreCallingIdentity(callingIdent);
   8447         }
   8448     }
   8449 
   8450     @Override
   8451     public Point getAppTaskThumbnailSize() {
   8452         synchronized (this) {
   8453             return new Point(mThumbnailWidth,  mThumbnailHeight);
   8454         }
   8455     }
   8456 
   8457     @Override
   8458     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
   8459         synchronized (this) {
   8460             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8461             if (r != null) {
   8462                 r.setTaskDescription(td);
   8463                 r.task.updateTaskDescription();
   8464             }
   8465         }
   8466     }
   8467 
   8468     @Override
   8469     public Bitmap getTaskDescriptionIcon(String filename) {
   8470         if (!FileUtils.isValidExtFilename(filename)
   8471                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
   8472             throw new IllegalArgumentException("Bad filename: " + filename);
   8473         }
   8474         return mTaskPersister.getTaskDescriptionIcon(filename);
   8475     }
   8476 
   8477     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   8478         mRecentTasks.remove(tr);
   8479         tr.removedFromRecents(mTaskPersister);
   8480         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   8481         Intent baseIntent = new Intent(
   8482                 tr.intent != null ? tr.intent : tr.affinityIntent);
   8483         ComponentName component = baseIntent.getComponent();
   8484         if (component == null) {
   8485             Slog.w(TAG, "Now component for base intent of task: " + tr);
   8486             return;
   8487         }
   8488 
   8489         // Find any running services associated with this app.
   8490         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
   8491 
   8492         if (killProcesses) {
   8493             // Find any running processes associated with this app.
   8494             final String pkg = component.getPackageName();
   8495             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   8496             ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   8497             for (int i=0; i<pmap.size(); i++) {
   8498                 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   8499                 for (int j=0; j<uids.size(); j++) {
   8500                     ProcessRecord proc = uids.valueAt(j);
   8501                     if (proc.userId != tr.userId) {
   8502                         continue;
   8503                     }
   8504                     if (!proc.pkgList.containsKey(pkg)) {
   8505                         continue;
   8506                     }
   8507                     procs.add(proc);
   8508                 }
   8509             }
   8510 
   8511             // Kill the running processes.
   8512             for (int i=0; i<procs.size(); i++) {
   8513                 ProcessRecord pr = procs.get(i);
   8514                 if (pr == mHomeProcess) {
   8515                     // Don't kill the home process along with tasks from the same package.
   8516                     continue;
   8517                 }
   8518                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   8519                     pr.kill("remove task", true);
   8520                 } else {
   8521                     pr.waitingToKill = "remove task";
   8522                 }
   8523             }
   8524         }
   8525     }
   8526 
   8527     /**
   8528      * Removes the task with the specified task id.
   8529      *
   8530      * @param taskId Identifier of the task to be removed.
   8531      * @param flags Additional operational flags.  May be 0 or
   8532      * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
   8533      * @return Returns true if the given task was found and removed.
   8534      */
   8535     private boolean removeTaskByIdLocked(int taskId, int flags) {
   8536         TaskRecord tr = recentTaskForIdLocked(taskId);
   8537         if (tr != null) {
   8538             tr.removeTaskActivitiesLocked();
   8539             cleanUpRemovedTaskLocked(tr, flags);
   8540             if (tr.isPersistable) {
   8541                 notifyTaskPersisterLocked(null, true);
   8542             }
   8543             return true;
   8544         }
   8545         return false;
   8546     }
   8547 
   8548     @Override
   8549     public boolean removeTask(int taskId, int flags) {
   8550         synchronized (this) {
   8551             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   8552                     "removeTask()");
   8553             long ident = Binder.clearCallingIdentity();
   8554             try {
   8555                 return removeTaskByIdLocked(taskId, flags);
   8556             } finally {
   8557                 Binder.restoreCallingIdentity(ident);
   8558             }
   8559         }
   8560     }
   8561 
   8562     /**
   8563      * TODO: Add mController hook
   8564      */
   8565     @Override
   8566     public void moveTaskToFront(int taskId, int flags, Bundle options) {
   8567         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8568                 "moveTaskToFront()");
   8569 
   8570         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
   8571         synchronized(this) {
   8572             moveTaskToFrontLocked(taskId, flags, options);
   8573         }
   8574     }
   8575 
   8576     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
   8577         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8578                 Binder.getCallingUid(), -1, -1, "Task to front")) {
   8579             ActivityOptions.abort(options);
   8580             return;
   8581         }
   8582         final long origId = Binder.clearCallingIdentity();
   8583         try {
   8584             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8585             if (task == null) {
   8586                 return;
   8587             }
   8588             if (mStackSupervisor.isLockTaskModeViolation(task)) {
   8589                 mStackSupervisor.showLockTaskToast();
   8590                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
   8591                 return;
   8592             }
   8593             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
   8594             if (prev != null && prev.isRecentsActivity()) {
   8595                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
   8596             }
   8597             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
   8598         } finally {
   8599             Binder.restoreCallingIdentity(origId);
   8600         }
   8601         ActivityOptions.abort(options);
   8602     }
   8603 
   8604     @Override
   8605     public void moveTaskToBack(int taskId) {
   8606         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8607                 "moveTaskToBack()");
   8608 
   8609         synchronized(this) {
   8610             TaskRecord tr = recentTaskForIdLocked(taskId);
   8611             if (tr != null) {
   8612                 if (tr == mStackSupervisor.mLockTaskModeTask) {
   8613                     mStackSupervisor.showLockTaskToast();
   8614                     return;
   8615                 }
   8616                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
   8617                 ActivityStack stack = tr.stack;
   8618                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
   8619                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8620                             Binder.getCallingUid(), -1, -1, "Task to back")) {
   8621                         return;
   8622                     }
   8623                 }
   8624                 final long origId = Binder.clearCallingIdentity();
   8625                 try {
   8626                     stack.moveTaskToBackLocked(taskId, null);
   8627                 } finally {
   8628                     Binder.restoreCallingIdentity(origId);
   8629                 }
   8630             }
   8631         }
   8632     }
   8633 
   8634     /**
   8635      * Moves an activity, and all of the other activities within the same task, to the bottom
   8636      * of the history stack.  The activity's order within the task is unchanged.
   8637      *
   8638      * @param token A reference to the activity we wish to move
   8639      * @param nonRoot If false then this only works if the activity is the root
   8640      *                of a task; if true it will work for any activity in a task.
   8641      * @return Returns true if the move completed, false if not.
   8642      */
   8643     @Override
   8644     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   8645         enforceNotIsolatedCaller("moveActivityTaskToBack");
   8646         synchronized(this) {
   8647             final long origId = Binder.clearCallingIdentity();
   8648             try {
   8649                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   8650                 if (taskId >= 0) {
   8651                     if ((mStackSupervisor.mLockTaskModeTask != null)
   8652                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
   8653                         mStackSupervisor.showLockTaskToast();
   8654                         return false;
   8655                     }
   8656                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
   8657                 }
   8658             } finally {
   8659                 Binder.restoreCallingIdentity(origId);
   8660             }
   8661         }
   8662         return false;
   8663     }
   8664 
   8665     @Override
   8666     public void moveTaskBackwards(int task) {
   8667         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   8668                 "moveTaskBackwards()");
   8669 
   8670         synchronized(this) {
   8671             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   8672                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
   8673                 return;
   8674             }
   8675             final long origId = Binder.clearCallingIdentity();
   8676             moveTaskBackwardsLocked(task);
   8677             Binder.restoreCallingIdentity(origId);
   8678         }
   8679     }
   8680 
   8681     private final void moveTaskBackwardsLocked(int task) {
   8682         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   8683     }
   8684 
   8685     @Override
   8686     public IBinder getHomeActivityToken() throws RemoteException {
   8687         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8688                 "getHomeActivityToken()");
   8689         synchronized (this) {
   8690             return mStackSupervisor.getHomeActivityToken();
   8691         }
   8692     }
   8693 
   8694     @Override
   8695     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
   8696             IActivityContainerCallback callback) throws RemoteException {
   8697         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8698                 "createActivityContainer()");
   8699         synchronized (this) {
   8700             if (parentActivityToken == null) {
   8701                 throw new IllegalArgumentException("parent token must not be null");
   8702             }
   8703             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
   8704             if (r == null) {
   8705                 return null;
   8706             }
   8707             if (callback == null) {
   8708                 throw new IllegalArgumentException("callback must not be null");
   8709             }
   8710             return mStackSupervisor.createActivityContainer(r, callback);
   8711         }
   8712     }
   8713 
   8714     @Override
   8715     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
   8716         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8717                 "deleteActivityContainer()");
   8718         synchronized (this) {
   8719             mStackSupervisor.deleteActivityContainer(container);
   8720         }
   8721     }
   8722 
   8723     @Override
   8724     public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
   8725             throws RemoteException {
   8726         synchronized (this) {
   8727             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
   8728             if (stack != null) {
   8729                 return stack.mActivityContainer;
   8730             }
   8731             return null;
   8732         }
   8733     }
   8734 
   8735     @Override
   8736     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   8737         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8738                 "moveTaskToStack()");
   8739         if (stackId == HOME_STACK_ID) {
   8740             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
   8741                     new RuntimeException("here").fillInStackTrace());
   8742         }
   8743         synchronized (this) {
   8744             long ident = Binder.clearCallingIdentity();
   8745             try {
   8746                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
   8747                         + stackId + " toTop=" + toTop);
   8748                 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
   8749             } finally {
   8750                 Binder.restoreCallingIdentity(ident);
   8751             }
   8752         }
   8753     }
   8754 
   8755     @Override
   8756     public void resizeStack(int stackBoxId, Rect bounds) {
   8757         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8758                 "resizeStackBox()");
   8759         long ident = Binder.clearCallingIdentity();
   8760         try {
   8761             mWindowManager.resizeStack(stackBoxId, bounds);
   8762         } finally {
   8763             Binder.restoreCallingIdentity(ident);
   8764         }
   8765     }
   8766 
   8767     @Override
   8768     public List<StackInfo> getAllStackInfos() {
   8769         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8770                 "getAllStackInfos()");
   8771         long ident = Binder.clearCallingIdentity();
   8772         try {
   8773             synchronized (this) {
   8774                 return mStackSupervisor.getAllStackInfosLocked();
   8775             }
   8776         } finally {
   8777             Binder.restoreCallingIdentity(ident);
   8778         }
   8779     }
   8780 
   8781     @Override
   8782     public StackInfo getStackInfo(int stackId) {
   8783         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8784                 "getStackInfo()");
   8785         long ident = Binder.clearCallingIdentity();
   8786         try {
   8787             synchronized (this) {
   8788                 return mStackSupervisor.getStackInfoLocked(stackId);
   8789             }
   8790         } finally {
   8791             Binder.restoreCallingIdentity(ident);
   8792         }
   8793     }
   8794 
   8795     @Override
   8796     public boolean isInHomeStack(int taskId) {
   8797         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8798                 "getStackInfo()");
   8799         long ident = Binder.clearCallingIdentity();
   8800         try {
   8801             synchronized (this) {
   8802                 TaskRecord tr = recentTaskForIdLocked(taskId);
   8803                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
   8804             }
   8805         } finally {
   8806             Binder.restoreCallingIdentity(ident);
   8807         }
   8808     }
   8809 
   8810     @Override
   8811     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   8812         synchronized(this) {
   8813             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   8814         }
   8815     }
   8816 
   8817     private boolean isLockTaskAuthorized(String pkg) {
   8818         final DevicePolicyManager dpm = (DevicePolicyManager)
   8819                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
   8820         try {
   8821             int uid = mContext.getPackageManager().getPackageUid(pkg,
   8822                     Binder.getCallingUserHandle().getIdentifier());
   8823             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
   8824         } catch (NameNotFoundException e) {
   8825             return false;
   8826         }
   8827     }
   8828 
   8829     void startLockTaskMode(TaskRecord task) {
   8830         final String pkg;
   8831         synchronized (this) {
   8832             pkg = task.intent.getComponent().getPackageName();
   8833         }
   8834         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
   8835         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
   8836             final TaskRecord taskRecord = task;
   8837             mHandler.post(new Runnable() {
   8838                 @Override
   8839                 public void run() {
   8840                     mLockToAppRequest.showLockTaskPrompt(taskRecord);
   8841                 }
   8842             });
   8843             return;
   8844         }
   8845         long ident = Binder.clearCallingIdentity();
   8846         try {
   8847             synchronized (this) {
   8848                 // Since we lost lock on task, make sure it is still there.
   8849                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
   8850                 if (task != null) {
   8851                     if (!isSystemInitiated
   8852                             && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
   8853                         throw new IllegalArgumentException("Invalid task, not in foreground");
   8854                     }
   8855                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
   8856                 }
   8857             }
   8858         } finally {
   8859             Binder.restoreCallingIdentity(ident);
   8860         }
   8861     }
   8862 
   8863     @Override
   8864     public void startLockTaskMode(int taskId) {
   8865         final TaskRecord task;
   8866         long ident = Binder.clearCallingIdentity();
   8867         try {
   8868             synchronized (this) {
   8869                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
   8870             }
   8871         } finally {
   8872             Binder.restoreCallingIdentity(ident);
   8873         }
   8874         if (task != null) {
   8875             startLockTaskMode(task);
   8876         }
   8877     }
   8878 
   8879     @Override
   8880     public void startLockTaskMode(IBinder token) {
   8881         final TaskRecord task;
   8882         long ident = Binder.clearCallingIdentity();
   8883         try {
   8884             synchronized (this) {
   8885                 final ActivityRecord r = ActivityRecord.forToken(token);
   8886                 if (r == null) {
   8887                     return;
   8888                 }
   8889                 task = r.task;
   8890             }
   8891         } finally {
   8892             Binder.restoreCallingIdentity(ident);
   8893         }
   8894         if (task != null) {
   8895             startLockTaskMode(task);
   8896         }
   8897     }
   8898 
   8899     @Override
   8900     public void startLockTaskModeOnCurrent() throws RemoteException {
   8901         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8902                 "startLockTaskModeOnCurrent");
   8903         ActivityRecord r = null;
   8904         synchronized (this) {
   8905             r = mStackSupervisor.topRunningActivityLocked();
   8906         }
   8907         startLockTaskMode(r.task);
   8908     }
   8909 
   8910     @Override
   8911     public void stopLockTaskMode() {
   8912         // Verify that the user matches the package of the intent for the TaskRecord
   8913         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
   8914         // and stopLockTaskMode.
   8915         final int callingUid = Binder.getCallingUid();
   8916         if (callingUid != Process.SYSTEM_UID) {
   8917             try {
   8918                 String pkg =
   8919                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
   8920                 int uid = mContext.getPackageManager().getPackageUid(pkg,
   8921                         Binder.getCallingUserHandle().getIdentifier());
   8922                 if (uid != callingUid) {
   8923                     throw new SecurityException("Invalid uid, expected " + uid);
   8924                 }
   8925             } catch (NameNotFoundException e) {
   8926                 Log.d(TAG, "stopLockTaskMode " + e);
   8927                 return;
   8928             }
   8929         }
   8930         long ident = Binder.clearCallingIdentity();
   8931         try {
   8932             Log.d(TAG, "stopLockTaskMode");
   8933             // Stop lock task
   8934             synchronized (this) {
   8935                 mStackSupervisor.setLockTaskModeLocked(null, false);
   8936             }
   8937         } finally {
   8938             Binder.restoreCallingIdentity(ident);
   8939         }
   8940     }
   8941 
   8942     @Override
   8943     public void stopLockTaskModeOnCurrent() throws RemoteException {
   8944         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   8945                 "stopLockTaskModeOnCurrent");
   8946         long ident = Binder.clearCallingIdentity();
   8947         try {
   8948             stopLockTaskMode();
   8949         } finally {
   8950             Binder.restoreCallingIdentity(ident);
   8951         }
   8952     }
   8953 
   8954     @Override
   8955     public boolean isInLockTaskMode() {
   8956         synchronized (this) {
   8957             return mStackSupervisor.isInLockTaskMode();
   8958         }
   8959     }
   8960 
   8961     // =========================================================
   8962     // CONTENT PROVIDERS
   8963     // =========================================================
   8964 
   8965     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   8966         List<ProviderInfo> providers = null;
   8967         try {
   8968             providers = AppGlobals.getPackageManager().
   8969                 queryContentProviders(app.processName, app.uid,
   8970                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   8971         } catch (RemoteException ex) {
   8972         }
   8973         if (DEBUG_MU)
   8974             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   8975         int userId = app.userId;
   8976         if (providers != null) {
   8977             int N = providers.size();
   8978             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   8979             for (int i=0; i<N; i++) {
   8980                 ProviderInfo cpi =
   8981                     (ProviderInfo)providers.get(i);
   8982                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   8983                         cpi.name, cpi.flags);
   8984                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   8985                     // This is a singleton provider, but a user besides the
   8986                     // default user is asking to initialize a process it runs
   8987                     // in...  well, no, it doesn't actually run in this process,
   8988                     // it runs in the process of the default user.  Get rid of it.
   8989                     providers.remove(i);
   8990                     N--;
   8991                     i--;
   8992                     continue;
   8993                 }
   8994 
   8995                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   8996                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   8997                 if (cpr == null) {
   8998                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   8999                     mProviderMap.putProviderByClass(comp, cpr);
   9000                 }
   9001                 if (DEBUG_MU)
   9002                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   9003                 app.pubProviders.put(cpi.name, cpr);
   9004                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   9005                     // Don't add this if it is a platform component that is marked
   9006                     // to run in multiple processes, because this is actually
   9007                     // part of the framework so doesn't make sense to track as a
   9008                     // separate apk in the process.
   9009                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
   9010                             mProcessStats);
   9011                 }
   9012                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   9013             }
   9014         }
   9015         return providers;
   9016     }
   9017 
   9018     /**
   9019      * Check if {@link ProcessRecord} has a possible chance at accessing the
   9020      * given {@link ProviderInfo}. Final permission checking is always done
   9021      * in {@link ContentProvider}.
   9022      */
   9023     private final String checkContentProviderPermissionLocked(
   9024             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
   9025         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   9026         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   9027         boolean checkedGrants = false;
   9028         if (checkUser) {
   9029             // Looking for cross-user grants before enforcing the typical cross-users permissions
   9030             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
   9031             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
   9032                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
   9033                     return null;
   9034                 }
   9035                 checkedGrants = true;
   9036             }
   9037             userId = handleIncomingUser(callingPid, callingUid, userId,
   9038                     false, ALLOW_NON_FULL,
   9039                     "checkContentProviderPermissionLocked " + cpi.authority, null);
   9040             if (userId != tmpTargetUserId) {
   9041                 // When we actually went to determine the final targer user ID, this ended
   9042                 // up different than our initial check for the authority.  This is because
   9043                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
   9044                 // SELF.  So we need to re-check the grants again.
   9045                 checkedGrants = false;
   9046             }
   9047         }
   9048         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   9049                 cpi.applicationInfo.uid, cpi.exported)
   9050                 == PackageManager.PERMISSION_GRANTED) {
   9051             return null;
   9052         }
   9053         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   9054                 cpi.applicationInfo.uid, cpi.exported)
   9055                 == PackageManager.PERMISSION_GRANTED) {
   9056             return null;
   9057         }
   9058 
   9059         PathPermission[] pps = cpi.pathPermissions;
   9060         if (pps != null) {
   9061             int i = pps.length;
   9062             while (i > 0) {
   9063                 i--;
   9064                 PathPermission pp = pps[i];
   9065                 String pprperm = pp.getReadPermission();
   9066                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
   9067                         cpi.applicationInfo.uid, cpi.exported)
   9068                         == PackageManager.PERMISSION_GRANTED) {
   9069                     return null;
   9070                 }
   9071                 String ppwperm = pp.getWritePermission();
   9072                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
   9073                         cpi.applicationInfo.uid, cpi.exported)
   9074                         == PackageManager.PERMISSION_GRANTED) {
   9075                     return null;
   9076                 }
   9077             }
   9078         }
   9079         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
   9080             return null;
   9081         }
   9082 
   9083         String msg;
   9084         if (!cpi.exported) {
   9085             msg = "Permission Denial: opening provider " + cpi.name
   9086                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9087                     + ", uid=" + callingUid + ") that is not exported from uid "
   9088                     + cpi.applicationInfo.uid;
   9089         } else {
   9090             msg = "Permission Denial: opening provider " + cpi.name
   9091                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   9092                     + ", uid=" + callingUid + ") requires "
   9093                     + cpi.readPermission + " or " + cpi.writePermission;
   9094         }
   9095         Slog.w(TAG, msg);
   9096         return msg;
   9097     }
   9098 
   9099     /**
   9100      * Returns if the ContentProvider has granted a uri to callingUid
   9101      */
   9102     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
   9103         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   9104         if (perms != null) {
   9105             for (int i=perms.size()-1; i>=0; i--) {
   9106                 GrantUri grantUri = perms.keyAt(i);
   9107                 if (grantUri.sourceUserId == userId || !checkUser) {
   9108                     if (matchesProvider(grantUri.uri, cpi)) {
   9109                         return true;
   9110                     }
   9111                 }
   9112             }
   9113         }
   9114         return false;
   9115     }
   9116 
   9117     /**
   9118      * Returns true if the uri authority is one of the authorities specified in the provider.
   9119      */
   9120     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
   9121         String uriAuth = uri.getAuthority();
   9122         String cpiAuth = cpi.authority;
   9123         if (cpiAuth.indexOf(';') == -1) {
   9124             return cpiAuth.equals(uriAuth);
   9125         }
   9126         String[] cpiAuths = cpiAuth.split(";");
   9127         int length = cpiAuths.length;
   9128         for (int i = 0; i < length; i++) {
   9129             if (cpiAuths[i].equals(uriAuth)) return true;
   9130         }
   9131         return false;
   9132     }
   9133 
   9134     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   9135             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9136         if (r != null) {
   9137             for (int i=0; i<r.conProviders.size(); i++) {
   9138                 ContentProviderConnection conn = r.conProviders.get(i);
   9139                 if (conn.provider == cpr) {
   9140                     if (DEBUG_PROVIDER) Slog.v(TAG,
   9141                             "Adding provider requested by "
   9142                             + r.processName + " from process "
   9143                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9144                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9145                     if (stable) {
   9146                         conn.stableCount++;
   9147                         conn.numStableIncs++;
   9148                     } else {
   9149                         conn.unstableCount++;
   9150                         conn.numUnstableIncs++;
   9151                     }
   9152                     return conn;
   9153                 }
   9154             }
   9155             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   9156             if (stable) {
   9157                 conn.stableCount = 1;
   9158                 conn.numStableIncs = 1;
   9159             } else {
   9160                 conn.unstableCount = 1;
   9161                 conn.numUnstableIncs = 1;
   9162             }
   9163             cpr.connections.add(conn);
   9164             r.conProviders.add(conn);
   9165             return conn;
   9166         }
   9167         cpr.addExternalProcessHandleLocked(externalProcessToken);
   9168         return null;
   9169     }
   9170 
   9171     boolean decProviderCountLocked(ContentProviderConnection conn,
   9172             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   9173         if (conn != null) {
   9174             cpr = conn.provider;
   9175             if (DEBUG_PROVIDER) Slog.v(TAG,
   9176                     "Removing provider requested by "
   9177                     + conn.client.processName + " from process "
   9178                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   9179                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   9180             if (stable) {
   9181                 conn.stableCount--;
   9182             } else {
   9183                 conn.unstableCount--;
   9184             }
   9185             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   9186                 cpr.connections.remove(conn);
   9187                 conn.client.conProviders.remove(conn);
   9188                 return true;
   9189             }
   9190             return false;
   9191         }
   9192         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   9193         return false;
   9194     }
   9195 
   9196     private void checkTime(long startTime, String where) {
   9197         long now = SystemClock.elapsedRealtime();
   9198         if ((now-startTime) > 1000) {
   9199             // If we are taking more than a second, log about it.
   9200             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
   9201         }
   9202     }
   9203 
   9204     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   9205             String name, IBinder token, boolean stable, int userId) {
   9206         ContentProviderRecord cpr;
   9207         ContentProviderConnection conn = null;
   9208         ProviderInfo cpi = null;
   9209 
   9210         synchronized(this) {
   9211             long startTime = SystemClock.elapsedRealtime();
   9212 
   9213             ProcessRecord r = null;
   9214             if (caller != null) {
   9215                 r = getRecordForAppLocked(caller);
   9216                 if (r == null) {
   9217                     throw new SecurityException(
   9218                             "Unable to find app for caller " + caller
   9219                           + " (pid=" + Binder.getCallingPid()
   9220                           + ") when getting content provider " + name);
   9221                 }
   9222             }
   9223 
   9224             boolean checkCrossUser = true;
   9225 
   9226             checkTime(startTime, "getContentProviderImpl: getProviderByName");
   9227 
   9228             // First check if this content provider has been published...
   9229             cpr = mProviderMap.getProviderByName(name, userId);
   9230             // If that didn't work, check if it exists for user 0 and then
   9231             // verify that it's a singleton provider before using it.
   9232             if (cpr == null && userId != UserHandle.USER_OWNER) {
   9233                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
   9234                 if (cpr != null) {
   9235                     cpi = cpr.info;
   9236                     if (isSingleton(cpi.processName, cpi.applicationInfo,
   9237                             cpi.name, cpi.flags)
   9238                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
   9239                         userId = UserHandle.USER_OWNER;
   9240                         checkCrossUser = false;
   9241                     } else {
   9242                         cpr = null;
   9243                         cpi = null;
   9244                     }
   9245                 }
   9246             }
   9247 
   9248             boolean providerRunning = cpr != null;
   9249             if (providerRunning) {
   9250                 cpi = cpr.info;
   9251                 String msg;
   9252                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9253                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
   9254                         != null) {
   9255                     throw new SecurityException(msg);
   9256                 }
   9257                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9258 
   9259                 if (r != null && cpr.canRunHere(r)) {
   9260                     // This provider has been published or is in the process
   9261                     // of being published...  but it is also allowed to run
   9262                     // in the caller's process, so don't make a connection
   9263                     // and just let the caller instantiate its own instance.
   9264                     ContentProviderHolder holder = cpr.newHolder(null);
   9265                     // don't give caller the provider object, it needs
   9266                     // to make its own.
   9267                     holder.provider = null;
   9268                     return holder;
   9269                 }
   9270 
   9271                 final long origId = Binder.clearCallingIdentity();
   9272 
   9273                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
   9274 
   9275                 // In this case the provider instance already exists, so we can
   9276                 // return it right away.
   9277                 conn = incProviderCountLocked(r, cpr, token, stable);
   9278                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   9279                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   9280                         // If this is a perceptible app accessing the provider,
   9281                         // make sure to count it as being accessed and thus
   9282                         // back up on the LRU list.  This is good because
   9283                         // content providers are often expensive to start.
   9284                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
   9285                         updateLruProcessLocked(cpr.proc, false, null);
   9286                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
   9287                     }
   9288                 }
   9289 
   9290                 if (cpr.proc != null) {
   9291                     if (false) {
   9292                         if (cpr.name.flattenToShortString().equals(
   9293                                 "com.android.providers.calendar/.CalendarProvider2")) {
   9294                             Slog.v(TAG, "****************** KILLING "
   9295                                 + cpr.name.flattenToShortString());
   9296                             Process.killProcess(cpr.proc.pid);
   9297                         }
   9298                     }
   9299                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
   9300                     boolean success = updateOomAdjLocked(cpr.proc);
   9301                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
   9302                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   9303                     // NOTE: there is still a race here where a signal could be
   9304                     // pending on the process even though we managed to update its
   9305                     // adj level.  Not sure what to do about this, but at least
   9306                     // the race is now smaller.
   9307                     if (!success) {
   9308                         // Uh oh...  it looks like the provider's process
   9309                         // has been killed on us.  We need to wait for a new
   9310                         // process to be started, and make sure its death
   9311                         // doesn't kill our process.
   9312                         Slog.i(TAG,
   9313                                 "Existing provider " + cpr.name.flattenToShortString()
   9314                                 + " is crashing; detaching " + r);
   9315                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   9316                         checkTime(startTime, "getContentProviderImpl: before appDied");
   9317                         appDiedLocked(cpr.proc);
   9318                         checkTime(startTime, "getContentProviderImpl: after appDied");
   9319                         if (!lastRef) {
   9320                             // This wasn't the last ref our process had on
   9321                             // the provider...  we have now been killed, bail.
   9322                             return null;
   9323                         }
   9324                         providerRunning = false;
   9325                         conn = null;
   9326                     }
   9327                 }
   9328 
   9329                 Binder.restoreCallingIdentity(origId);
   9330             }
   9331 
   9332             boolean singleton;
   9333             if (!providerRunning) {
   9334                 try {
   9335                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
   9336                     cpi = AppGlobals.getPackageManager().
   9337                         resolveContentProvider(name,
   9338                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   9339                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
   9340                 } catch (RemoteException ex) {
   9341                 }
   9342                 if (cpi == null) {
   9343                     return null;
   9344                 }
   9345                 // If the provider is a singleton AND
   9346                 // (it's a call within the same user || the provider is a
   9347                 // privileged app)
   9348                 // Then allow connecting to the singleton provider
   9349                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   9350                         cpi.name, cpi.flags)
   9351                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
   9352                 if (singleton) {
   9353                     userId = UserHandle.USER_OWNER;
   9354                 }
   9355                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   9356                 checkTime(startTime, "getContentProviderImpl: got app info for user");
   9357 
   9358                 String msg;
   9359                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
   9360                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
   9361                         != null) {
   9362                     throw new SecurityException(msg);
   9363                 }
   9364                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
   9365 
   9366                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   9367                         && !cpi.processName.equals("system")) {
   9368                     // If this content provider does not run in the system
   9369                     // process, and the system is not yet ready to run other
   9370                     // processes, then fail fast instead of hanging.
   9371                     throw new IllegalArgumentException(
   9372                             "Attempt to launch content provider before system ready");
   9373                 }
   9374 
   9375                 // Make sure that the user who owns this provider is started.  If not,
   9376                 // we don't want to allow it to run.
   9377                 if (mStartedUsers.get(userId) == null) {
   9378                     Slog.w(TAG, "Unable to launch app "
   9379                             + cpi.applicationInfo.packageName + "/"
   9380                             + cpi.applicationInfo.uid + " for provider "
   9381                             + name + ": user " + userId + " is stopped");
   9382                     return null;
   9383                 }
   9384 
   9385                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   9386                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
   9387                 cpr = mProviderMap.getProviderByClass(comp, userId);
   9388                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
   9389                 final boolean firstClass = cpr == null;
   9390                 if (firstClass) {
   9391                     final long ident = Binder.clearCallingIdentity();
   9392                     try {
   9393                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
   9394                         ApplicationInfo ai =
   9395                             AppGlobals.getPackageManager().
   9396                                 getApplicationInfo(
   9397                                         cpi.applicationInfo.packageName,
   9398                                         STOCK_PM_FLAGS, userId);
   9399                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
   9400                         if (ai == null) {
   9401                             Slog.w(TAG, "No package info for content provider "
   9402                                     + cpi.name);
   9403                             return null;
   9404                         }
   9405                         ai = getAppInfoForUser(ai, userId);
   9406                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   9407                     } catch (RemoteException ex) {
   9408                         // pm is in same process, this will never happen.
   9409                     } finally {
   9410                         Binder.restoreCallingIdentity(ident);
   9411                     }
   9412                 }
   9413 
   9414                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
   9415 
   9416                 if (r != null && cpr.canRunHere(r)) {
   9417                     // If this is a multiprocess provider, then just return its
   9418                     // info and allow the caller to instantiate it.  Only do
   9419                     // this if the provider is the same user as the caller's
   9420                     // process, or can run as root (so can be in any process).
   9421                     return cpr.newHolder(null);
   9422                 }
   9423 
   9424                 if (DEBUG_PROVIDER) {
   9425                     RuntimeException e = new RuntimeException("here");
   9426                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
   9427                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   9428                 }
   9429 
   9430                 // This is single process, and our app is now connecting to it.
   9431                 // See if we are already in the process of launching this
   9432                 // provider.
   9433                 final int N = mLaunchingProviders.size();
   9434                 int i;
   9435                 for (i=0; i<N; i++) {
   9436                     if (mLaunchingProviders.get(i) == cpr) {
   9437                         break;
   9438                     }
   9439                 }
   9440 
   9441                 // If the provider is not already being launched, then get it
   9442                 // started.
   9443                 if (i >= N) {
   9444                     final long origId = Binder.clearCallingIdentity();
   9445 
   9446                     try {
   9447                         // Content provider is now in use, its package can't be stopped.
   9448                         try {
   9449                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
   9450                             AppGlobals.getPackageManager().setPackageStoppedState(
   9451                                     cpr.appInfo.packageName, false, userId);
   9452                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
   9453                         } catch (RemoteException e) {
   9454                         } catch (IllegalArgumentException e) {
   9455                             Slog.w(TAG, "Failed trying to unstop package "
   9456                                     + cpr.appInfo.packageName + ": " + e);
   9457                         }
   9458 
   9459                         // Use existing process if already started
   9460                         checkTime(startTime, "getContentProviderImpl: looking for process record");
   9461                         ProcessRecord proc = getProcessRecordLocked(
   9462                                 cpi.processName, cpr.appInfo.uid, false);
   9463                         if (proc != null && proc.thread != null) {
   9464                             if (DEBUG_PROVIDER) {
   9465                                 Slog.d(TAG, "Installing in existing process " + proc);
   9466                             }
   9467                             checkTime(startTime, "getContentProviderImpl: scheduling install");
   9468                             proc.pubProviders.put(cpi.name, cpr);
   9469                             try {
   9470                                 proc.thread.scheduleInstallProvider(cpi);
   9471                             } catch (RemoteException e) {
   9472                             }
   9473                         } else {
   9474                             checkTime(startTime, "getContentProviderImpl: before start process");
   9475                             proc = startProcessLocked(cpi.processName,
   9476                                     cpr.appInfo, false, 0, "content provider",
   9477                                     new ComponentName(cpi.applicationInfo.packageName,
   9478                                             cpi.name), false, false, false);
   9479                             checkTime(startTime, "getContentProviderImpl: after start process");
   9480                             if (proc == null) {
   9481                                 Slog.w(TAG, "Unable to launch app "
   9482                                         + cpi.applicationInfo.packageName + "/"
   9483                                         + cpi.applicationInfo.uid + " for provider "
   9484                                         + name + ": process is bad");
   9485                                 return null;
   9486                             }
   9487                         }
   9488                         cpr.launchingApp = proc;
   9489                         mLaunchingProviders.add(cpr);
   9490                     } finally {
   9491                         Binder.restoreCallingIdentity(origId);
   9492                     }
   9493                 }
   9494 
   9495                 checkTime(startTime, "getContentProviderImpl: updating data structures");
   9496 
   9497                 // Make sure the provider is published (the same provider class
   9498                 // may be published under multiple names).
   9499                 if (firstClass) {
   9500                     mProviderMap.putProviderByClass(comp, cpr);
   9501                 }
   9502 
   9503                 mProviderMap.putProviderByName(name, cpr);
   9504                 conn = incProviderCountLocked(r, cpr, token, stable);
   9505                 if (conn != null) {
   9506                     conn.waiting = true;
   9507                 }
   9508             }
   9509             checkTime(startTime, "getContentProviderImpl: done!");
   9510         }
   9511 
   9512         // Wait for the provider to be published...
   9513         synchronized (cpr) {
   9514             while (cpr.provider == null) {
   9515                 if (cpr.launchingApp == null) {
   9516                     Slog.w(TAG, "Unable to launch app "
   9517                             + cpi.applicationInfo.packageName + "/"
   9518                             + cpi.applicationInfo.uid + " for provider "
   9519                             + name + ": launching app became null");
   9520                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   9521                             UserHandle.getUserId(cpi.applicationInfo.uid),
   9522                             cpi.applicationInfo.packageName,
   9523                             cpi.applicationInfo.uid, name);
   9524                     return null;
   9525                 }
   9526                 try {
   9527                     if (DEBUG_MU) {
   9528                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   9529                                 + cpr.launchingApp);
   9530                     }
   9531                     if (conn != null) {
   9532                         conn.waiting = true;
   9533                     }
   9534                     cpr.wait();
   9535                 } catch (InterruptedException ex) {
   9536                 } finally {
   9537                     if (conn != null) {
   9538                         conn.waiting = false;
   9539                     }
   9540                 }
   9541             }
   9542         }
   9543         return cpr != null ? cpr.newHolder(conn) : null;
   9544     }
   9545 
   9546     @Override
   9547     public final ContentProviderHolder getContentProvider(
   9548             IApplicationThread caller, String name, int userId, boolean stable) {
   9549         enforceNotIsolatedCaller("getContentProvider");
   9550         if (caller == null) {
   9551             String msg = "null IApplicationThread when getting content provider "
   9552                     + name;
   9553             Slog.w(TAG, msg);
   9554             throw new SecurityException(msg);
   9555         }
   9556         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
   9557         // with cross-user grant.
   9558         return getContentProviderImpl(caller, name, null, stable, userId);
   9559     }
   9560 
   9561     public ContentProviderHolder getContentProviderExternal(
   9562             String name, int userId, IBinder token) {
   9563         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9564             "Do not have permission in call getContentProviderExternal()");
   9565         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   9566                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
   9567         return getContentProviderExternalUnchecked(name, token, userId);
   9568     }
   9569 
   9570     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   9571             IBinder token, int userId) {
   9572         return getContentProviderImpl(null, name, token, true, userId);
   9573     }
   9574 
   9575     /**
   9576      * Drop a content provider from a ProcessRecord's bookkeeping
   9577      */
   9578     public void removeContentProvider(IBinder connection, boolean stable) {
   9579         enforceNotIsolatedCaller("removeContentProvider");
   9580         long ident = Binder.clearCallingIdentity();
   9581         try {
   9582             synchronized (this) {
   9583                 ContentProviderConnection conn;
   9584                 try {
   9585                     conn = (ContentProviderConnection)connection;
   9586                 } catch (ClassCastException e) {
   9587                     String msg ="removeContentProvider: " + connection
   9588                             + " not a ContentProviderConnection";
   9589                     Slog.w(TAG, msg);
   9590                     throw new IllegalArgumentException(msg);
   9591                 }
   9592                 if (conn == null) {
   9593                     throw new NullPointerException("connection is null");
   9594                 }
   9595                 if (decProviderCountLocked(conn, null, null, stable)) {
   9596                     updateOomAdjLocked();
   9597                 }
   9598             }
   9599         } finally {
   9600             Binder.restoreCallingIdentity(ident);
   9601         }
   9602     }
   9603 
   9604     public void removeContentProviderExternal(String name, IBinder token) {
   9605         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   9606             "Do not have permission in call removeContentProviderExternal()");
   9607         int userId = UserHandle.getCallingUserId();
   9608         long ident = Binder.clearCallingIdentity();
   9609         try {
   9610             removeContentProviderExternalUnchecked(name, token, userId);
   9611         } finally {
   9612             Binder.restoreCallingIdentity(ident);
   9613         }
   9614     }
   9615 
   9616     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   9617         synchronized (this) {
   9618             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   9619             if(cpr == null) {
   9620                 //remove from mProvidersByClass
   9621                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   9622                 return;
   9623             }
   9624 
   9625             //update content provider record entry info
   9626             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   9627             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   9628             if (localCpr.hasExternalProcessHandles()) {
   9629                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   9630                     updateOomAdjLocked();
   9631                 } else {
   9632                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   9633                             + " with no external reference for token: "
   9634                             + token + ".");
   9635                 }
   9636             } else {
   9637                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   9638                         + " with no external references.");
   9639             }
   9640         }
   9641     }
   9642 
   9643     public final void publishContentProviders(IApplicationThread caller,
   9644             List<ContentProviderHolder> providers) {
   9645         if (providers == null) {
   9646             return;
   9647         }
   9648 
   9649         enforceNotIsolatedCaller("publishContentProviders");
   9650         synchronized (this) {
   9651             final ProcessRecord r = getRecordForAppLocked(caller);
   9652             if (DEBUG_MU)
   9653                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   9654             if (r == null) {
   9655                 throw new SecurityException(
   9656                         "Unable to find app for caller " + caller
   9657                       + " (pid=" + Binder.getCallingPid()
   9658                       + ") when publishing content providers");
   9659             }
   9660 
   9661             final long origId = Binder.clearCallingIdentity();
   9662 
   9663             final int N = providers.size();
   9664             for (int i=0; i<N; i++) {
   9665                 ContentProviderHolder src = providers.get(i);
   9666                 if (src == null || src.info == null || src.provider == null) {
   9667                     continue;
   9668                 }
   9669                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   9670                 if (DEBUG_MU)
   9671                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   9672                 if (dst != null) {
   9673                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   9674                     mProviderMap.putProviderByClass(comp, dst);
   9675                     String names[] = dst.info.authority.split(";");
   9676                     for (int j = 0; j < names.length; j++) {
   9677                         mProviderMap.putProviderByName(names[j], dst);
   9678                     }
   9679 
   9680                     int NL = mLaunchingProviders.size();
   9681                     int j;
   9682                     for (j=0; j<NL; j++) {
   9683                         if (mLaunchingProviders.get(j) == dst) {
   9684                             mLaunchingProviders.remove(j);
   9685                             j--;
   9686                             NL--;
   9687                         }
   9688                     }
   9689                     synchronized (dst) {
   9690                         dst.provider = src.provider;
   9691                         dst.proc = r;
   9692                         dst.notifyAll();
   9693                     }
   9694                     updateOomAdjLocked(r);
   9695                 }
   9696             }
   9697 
   9698             Binder.restoreCallingIdentity(origId);
   9699         }
   9700     }
   9701 
   9702     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   9703         ContentProviderConnection conn;
   9704         try {
   9705             conn = (ContentProviderConnection)connection;
   9706         } catch (ClassCastException e) {
   9707             String msg ="refContentProvider: " + connection
   9708                     + " not a ContentProviderConnection";
   9709             Slog.w(TAG, msg);
   9710             throw new IllegalArgumentException(msg);
   9711         }
   9712         if (conn == null) {
   9713             throw new NullPointerException("connection is null");
   9714         }
   9715 
   9716         synchronized (this) {
   9717             if (stable > 0) {
   9718                 conn.numStableIncs += stable;
   9719             }
   9720             stable = conn.stableCount + stable;
   9721             if (stable < 0) {
   9722                 throw new IllegalStateException("stableCount < 0: " + stable);
   9723             }
   9724 
   9725             if (unstable > 0) {
   9726                 conn.numUnstableIncs += unstable;
   9727             }
   9728             unstable = conn.unstableCount + unstable;
   9729             if (unstable < 0) {
   9730                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   9731             }
   9732 
   9733             if ((stable+unstable) <= 0) {
   9734                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   9735                         + stable + " unstable=" + unstable);
   9736             }
   9737             conn.stableCount = stable;
   9738             conn.unstableCount = unstable;
   9739             return !conn.dead;
   9740         }
   9741     }
   9742 
   9743     public void unstableProviderDied(IBinder connection) {
   9744         ContentProviderConnection conn;
   9745         try {
   9746             conn = (ContentProviderConnection)connection;
   9747         } catch (ClassCastException e) {
   9748             String msg ="refContentProvider: " + connection
   9749                     + " not a ContentProviderConnection";
   9750             Slog.w(TAG, msg);
   9751             throw new IllegalArgumentException(msg);
   9752         }
   9753         if (conn == null) {
   9754             throw new NullPointerException("connection is null");
   9755         }
   9756 
   9757         // Safely retrieve the content provider associated with the connection.
   9758         IContentProvider provider;
   9759         synchronized (this) {
   9760             provider = conn.provider.provider;
   9761         }
   9762 
   9763         if (provider == null) {
   9764             // Um, yeah, we're way ahead of you.
   9765             return;
   9766         }
   9767 
   9768         // Make sure the caller is being honest with us.
   9769         if (provider.asBinder().pingBinder()) {
   9770             // Er, no, still looks good to us.
   9771             synchronized (this) {
   9772                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   9773                         + " says " + conn + " died, but we don't agree");
   9774                 return;
   9775             }
   9776         }
   9777 
   9778         // Well look at that!  It's dead!
   9779         synchronized (this) {
   9780             if (conn.provider.provider != provider) {
   9781                 // But something changed...  good enough.
   9782                 return;
   9783             }
   9784 
   9785             ProcessRecord proc = conn.provider.proc;
   9786             if (proc == null || proc.thread == null) {
   9787                 // Seems like the process is already cleaned up.
   9788                 return;
   9789             }
   9790 
   9791             // As far as we're concerned, this is just like receiving a
   9792             // death notification...  just a bit prematurely.
   9793             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   9794                     + ") early provider death");
   9795             final long ident = Binder.clearCallingIdentity();
   9796             try {
   9797                 appDiedLocked(proc);
   9798             } finally {
   9799                 Binder.restoreCallingIdentity(ident);
   9800             }
   9801         }
   9802     }
   9803 
   9804     @Override
   9805     public void appNotRespondingViaProvider(IBinder connection) {
   9806         enforceCallingPermission(
   9807                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   9808 
   9809         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   9810         if (conn == null) {
   9811             Slog.w(TAG, "ContentProviderConnection is null");
   9812             return;
   9813         }
   9814 
   9815         final ProcessRecord host = conn.provider.proc;
   9816         if (host == null) {
   9817             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   9818             return;
   9819         }
   9820 
   9821         final long token = Binder.clearCallingIdentity();
   9822         try {
   9823             appNotResponding(host, null, null, false, "ContentProvider not responding");
   9824         } finally {
   9825             Binder.restoreCallingIdentity(token);
   9826         }
   9827     }
   9828 
   9829     public final void installSystemProviders() {
   9830         List<ProviderInfo> providers;
   9831         synchronized (this) {
   9832             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
   9833             providers = generateApplicationProvidersLocked(app);
   9834             if (providers != null) {
   9835                 for (int i=providers.size()-1; i>=0; i--) {
   9836                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   9837                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   9838                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   9839                                 + ": not system .apk");
   9840                         providers.remove(i);
   9841                     }
   9842                 }
   9843             }
   9844         }
   9845         if (providers != null) {
   9846             mSystemThread.installSystemProviders(providers);
   9847         }
   9848 
   9849         mCoreSettingsObserver = new CoreSettingsObserver(this);
   9850 
   9851         //mUsageStatsService.monitorPackages();
   9852     }
   9853 
   9854     /**
   9855      * Allows apps to retrieve the MIME type of a URI.
   9856      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
   9857      * users, then it does not need permission to access the ContentProvider.
   9858      * Either, it needs cross-user uri grants.
   9859      *
   9860      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   9861      *
   9862      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   9863      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   9864      */
   9865     public String getProviderMimeType(Uri uri, int userId) {
   9866         enforceNotIsolatedCaller("getProviderMimeType");
   9867         final String name = uri.getAuthority();
   9868         int callingUid = Binder.getCallingUid();
   9869         int callingPid = Binder.getCallingPid();
   9870         long ident = 0;
   9871         boolean clearedIdentity = false;
   9872         userId = unsafeConvertIncomingUser(userId);
   9873         if (canClearIdentity(callingPid, callingUid, userId)) {
   9874             clearedIdentity = true;
   9875             ident = Binder.clearCallingIdentity();
   9876         }
   9877         ContentProviderHolder holder = null;
   9878         try {
   9879             holder = getContentProviderExternalUnchecked(name, null, userId);
   9880             if (holder != null) {
   9881                 return holder.provider.getType(uri);
   9882             }
   9883         } catch (RemoteException e) {
   9884             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   9885             return null;
   9886         } finally {
   9887             // We need to clear the identity to call removeContentProviderExternalUnchecked
   9888             if (!clearedIdentity) {
   9889                 ident = Binder.clearCallingIdentity();
   9890             }
   9891             try {
   9892                 if (holder != null) {
   9893                     removeContentProviderExternalUnchecked(name, null, userId);
   9894                 }
   9895             } finally {
   9896                 Binder.restoreCallingIdentity(ident);
   9897             }
   9898         }
   9899 
   9900         return null;
   9901     }
   9902 
   9903     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
   9904         if (UserHandle.getUserId(callingUid) == userId) {
   9905             return true;
   9906         }
   9907         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   9908                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
   9909                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   9910                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   9911                 return true;
   9912         }
   9913         return false;
   9914     }
   9915 
   9916     // =========================================================
   9917     // GLOBAL MANAGEMENT
   9918     // =========================================================
   9919 
   9920     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   9921             boolean isolated, int isolatedUid) {
   9922         String proc = customProcess != null ? customProcess : info.processName;
   9923         BatteryStatsImpl.Uid.Proc ps = null;
   9924         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   9925         int uid = info.uid;
   9926         if (isolated) {
   9927             if (isolatedUid == 0) {
   9928                 int userId = UserHandle.getUserId(uid);
   9929                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   9930                 while (true) {
   9931                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   9932                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   9933                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   9934                     }
   9935                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   9936                     mNextIsolatedProcessUid++;
   9937                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   9938                         // No process for this uid, use it.
   9939                         break;
   9940                     }
   9941                     stepsLeft--;
   9942                     if (stepsLeft <= 0) {
   9943                         return null;
   9944                     }
   9945                 }
   9946             } else {
   9947                 // Special case for startIsolatedProcess (internal only), where
   9948                 // the uid of the isolated process is specified by the caller.
   9949                 uid = isolatedUid;
   9950             }
   9951         }
   9952         return new ProcessRecord(stats, info, proc, uid);
   9953     }
   9954 
   9955     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
   9956             String abiOverride) {
   9957         ProcessRecord app;
   9958         if (!isolated) {
   9959             app = getProcessRecordLocked(info.processName, info.uid, true);
   9960         } else {
   9961             app = null;
   9962         }
   9963 
   9964         if (app == null) {
   9965             app = newProcessRecordLocked(info, null, isolated, 0);
   9966             mProcessNames.put(info.processName, app.uid, app);
   9967             if (isolated) {
   9968                 mIsolatedProcesses.put(app.uid, app);
   9969             }
   9970             updateLruProcessLocked(app, false, null);
   9971             updateOomAdjLocked();
   9972         }
   9973 
   9974         // This package really, really can not be stopped.
   9975         try {
   9976             AppGlobals.getPackageManager().setPackageStoppedState(
   9977                     info.packageName, false, UserHandle.getUserId(app.uid));
   9978         } catch (RemoteException e) {
   9979         } catch (IllegalArgumentException e) {
   9980             Slog.w(TAG, "Failed trying to unstop package "
   9981                     + info.packageName + ": " + e);
   9982         }
   9983 
   9984         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   9985                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   9986             app.persistent = true;
   9987             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   9988         }
   9989         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   9990             mPersistentStartingProcesses.add(app);
   9991             startProcessLocked(app, "added application", app.processName, abiOverride,
   9992                     null /* entryPoint */, null /* entryPointArgs */);
   9993         }
   9994 
   9995         return app;
   9996     }
   9997 
   9998     public void unhandledBack() {
   9999         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   10000                 "unhandledBack()");
   10001 
   10002         synchronized(this) {
   10003             final long origId = Binder.clearCallingIdentity();
   10004             try {
   10005                 getFocusedStack().unhandledBackLocked();
   10006             } finally {
   10007                 Binder.restoreCallingIdentity(origId);
   10008             }
   10009         }
   10010     }
   10011 
   10012     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   10013         enforceNotIsolatedCaller("openContentUri");
   10014         final int userId = UserHandle.getCallingUserId();
   10015         String name = uri.getAuthority();
   10016         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   10017         ParcelFileDescriptor pfd = null;
   10018         if (cph != null) {
   10019             // We record the binder invoker's uid in thread-local storage before
   10020             // going to the content provider to open the file.  Later, in the code
   10021             // that handles all permissions checks, we look for this uid and use
   10022             // that rather than the Activity Manager's own uid.  The effect is that
   10023             // we do the check against the caller's permissions even though it looks
   10024             // to the content provider like the Activity Manager itself is making
   10025             // the request.
   10026             sCallerIdentity.set(new Identity(
   10027                     Binder.getCallingPid(), Binder.getCallingUid()));
   10028             try {
   10029                 pfd = cph.provider.openFile(null, uri, "r", null);
   10030             } catch (FileNotFoundException e) {
   10031                 // do nothing; pfd will be returned null
   10032             } finally {
   10033                 // Ensure that whatever happens, we clean up the identity state
   10034                 sCallerIdentity.remove();
   10035             }
   10036 
   10037             // We've got the fd now, so we're done with the provider.
   10038             removeContentProviderExternalUnchecked(name, null, userId);
   10039         } else {
   10040             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   10041         }
   10042         return pfd;
   10043     }
   10044 
   10045     // Actually is sleeping or shutting down or whatever else in the future
   10046     // is an inactive state.
   10047     public boolean isSleepingOrShuttingDown() {
   10048         return isSleeping() || mShuttingDown;
   10049     }
   10050 
   10051     public boolean isSleeping() {
   10052         return mSleeping;
   10053     }
   10054 
   10055     void goingToSleep() {
   10056         synchronized(this) {
   10057             mWentToSleep = true;
   10058             goToSleepIfNeededLocked();
   10059         }
   10060     }
   10061 
   10062     void finishRunningVoiceLocked() {
   10063         if (mRunningVoice) {
   10064             mRunningVoice = false;
   10065             goToSleepIfNeededLocked();
   10066         }
   10067     }
   10068 
   10069     void goToSleepIfNeededLocked() {
   10070         if (mWentToSleep && !mRunningVoice) {
   10071             if (!mSleeping) {
   10072                 mSleeping = true;
   10073                 mStackSupervisor.goingToSleepLocked();
   10074 
   10075                 // Initialize the wake times of all processes.
   10076                 checkExcessivePowerUsageLocked(false);
   10077                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10078                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   10079                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   10080             }
   10081         }
   10082     }
   10083 
   10084     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
   10085         if (task != null && task.stack != null && task.stack.isHomeStack()) {
   10086             // Never persist the home stack.
   10087             return;
   10088         }
   10089         mTaskPersister.wakeup(task, flush);
   10090     }
   10091 
   10092     @Override
   10093     public boolean shutdown(int timeout) {
   10094         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   10095                 != PackageManager.PERMISSION_GRANTED) {
   10096             throw new SecurityException("Requires permission "
   10097                     + android.Manifest.permission.SHUTDOWN);
   10098         }
   10099 
   10100         boolean timedout = false;
   10101 
   10102         synchronized(this) {
   10103             mShuttingDown = true;
   10104             updateEventDispatchingLocked();
   10105             timedout = mStackSupervisor.shutdownLocked(timeout);
   10106         }
   10107 
   10108         mAppOpsService.shutdown();
   10109         if (mUsageStatsService != null) {
   10110             mUsageStatsService.prepareShutdown();
   10111         }
   10112         mBatteryStatsService.shutdown();
   10113         synchronized (this) {
   10114             mProcessStats.shutdownLocked();
   10115         }
   10116         notifyTaskPersisterLocked(null, true);
   10117 
   10118         return timedout;
   10119     }
   10120 
   10121     public final void activitySlept(IBinder token) {
   10122         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
   10123 
   10124         final long origId = Binder.clearCallingIdentity();
   10125 
   10126         synchronized (this) {
   10127             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10128             if (r != null) {
   10129                 mStackSupervisor.activitySleptLocked(r);
   10130             }
   10131         }
   10132 
   10133         Binder.restoreCallingIdentity(origId);
   10134     }
   10135 
   10136     void logLockScreen(String msg) {
   10137         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
   10138                 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
   10139                 mWentToSleep + " mSleeping=" + mSleeping);
   10140     }
   10141 
   10142     private void comeOutOfSleepIfNeededLocked() {
   10143         if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
   10144             if (mSleeping) {
   10145                 mSleeping = false;
   10146                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
   10147             }
   10148         }
   10149     }
   10150 
   10151     void wakingUp() {
   10152         synchronized(this) {
   10153             mWentToSleep = false;
   10154             comeOutOfSleepIfNeededLocked();
   10155         }
   10156     }
   10157 
   10158     void startRunningVoiceLocked() {
   10159         if (!mRunningVoice) {
   10160             mRunningVoice = true;
   10161             comeOutOfSleepIfNeededLocked();
   10162         }
   10163     }
   10164 
   10165     private void updateEventDispatchingLocked() {
   10166         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
   10167     }
   10168 
   10169     public void setLockScreenShown(boolean shown) {
   10170         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   10171                 != PackageManager.PERMISSION_GRANTED) {
   10172             throw new SecurityException("Requires permission "
   10173                     + android.Manifest.permission.DEVICE_POWER);
   10174         }
   10175 
   10176         synchronized(this) {
   10177             long ident = Binder.clearCallingIdentity();
   10178             try {
   10179                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
   10180                 mLockScreenShown = shown;
   10181                 comeOutOfSleepIfNeededLocked();
   10182             } finally {
   10183                 Binder.restoreCallingIdentity(ident);
   10184             }
   10185         }
   10186     }
   10187 
   10188     @Override
   10189     public void stopAppSwitches() {
   10190         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10191                 != PackageManager.PERMISSION_GRANTED) {
   10192             throw new SecurityException("Requires permission "
   10193                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10194         }
   10195 
   10196         synchronized(this) {
   10197             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   10198                     + APP_SWITCH_DELAY_TIME;
   10199             mDidAppSwitch = false;
   10200             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10201             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   10202             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   10203         }
   10204     }
   10205 
   10206     public void resumeAppSwitches() {
   10207         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   10208                 != PackageManager.PERMISSION_GRANTED) {
   10209             throw new SecurityException("Requires permission "
   10210                     + android.Manifest.permission.STOP_APP_SWITCHES);
   10211         }
   10212 
   10213         synchronized(this) {
   10214             // Note that we don't execute any pending app switches... we will
   10215             // let those wait until either the timeout, or the next start
   10216             // activity request.
   10217             mAppSwitchesAllowedTime = 0;
   10218         }
   10219     }
   10220 
   10221     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
   10222             int callingPid, int callingUid, String name) {
   10223         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   10224             return true;
   10225         }
   10226 
   10227         int perm = checkComponentPermission(
   10228                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
   10229                 sourceUid, -1, true);
   10230         if (perm == PackageManager.PERMISSION_GRANTED) {
   10231             return true;
   10232         }
   10233 
   10234         // If the actual IPC caller is different from the logical source, then
   10235         // also see if they are allowed to control app switches.
   10236         if (callingUid != -1 && callingUid != sourceUid) {
   10237             perm = checkComponentPermission(
   10238                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   10239                     callingUid, -1, true);
   10240             if (perm == PackageManager.PERMISSION_GRANTED) {
   10241                 return true;
   10242             }
   10243         }
   10244 
   10245         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
   10246         return false;
   10247     }
   10248 
   10249     public void setDebugApp(String packageName, boolean waitForDebugger,
   10250             boolean persistent) {
   10251         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   10252                 "setDebugApp()");
   10253 
   10254         long ident = Binder.clearCallingIdentity();
   10255         try {
   10256             // Note that this is not really thread safe if there are multiple
   10257             // callers into it at the same time, but that's not a situation we
   10258             // care about.
   10259             if (persistent) {
   10260                 final ContentResolver resolver = mContext.getContentResolver();
   10261                 Settings.Global.putString(
   10262                     resolver, Settings.Global.DEBUG_APP,
   10263                     packageName);
   10264                 Settings.Global.putInt(
   10265                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   10266                     waitForDebugger ? 1 : 0);
   10267             }
   10268 
   10269             synchronized (this) {
   10270                 if (!persistent) {
   10271                     mOrigDebugApp = mDebugApp;
   10272                     mOrigWaitForDebugger = mWaitForDebugger;
   10273                 }
   10274                 mDebugApp = packageName;
   10275                 mWaitForDebugger = waitForDebugger;
   10276                 mDebugTransient = !persistent;
   10277                 if (packageName != null) {
   10278                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   10279                             false, UserHandle.USER_ALL, "set debug app");
   10280                 }
   10281             }
   10282         } finally {
   10283             Binder.restoreCallingIdentity(ident);
   10284         }
   10285     }
   10286 
   10287     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   10288         synchronized (this) {
   10289             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10290             if (!isDebuggable) {
   10291                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10292                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10293                 }
   10294             }
   10295 
   10296             mOpenGlTraceApp = processName;
   10297         }
   10298     }
   10299 
   10300     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
   10301         synchronized (this) {
   10302             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   10303             if (!isDebuggable) {
   10304                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   10305                     throw new SecurityException("Process not debuggable: " + app.packageName);
   10306                 }
   10307             }
   10308             mProfileApp = processName;
   10309             mProfileFile = profilerInfo.profileFile;
   10310             if (mProfileFd != null) {
   10311                 try {
   10312                     mProfileFd.close();
   10313                 } catch (IOException e) {
   10314                 }
   10315                 mProfileFd = null;
   10316             }
   10317             mProfileFd = profilerInfo.profileFd;
   10318             mSamplingInterval = profilerInfo.samplingInterval;
   10319             mAutoStopProfiler = profilerInfo.autoStopProfiler;
   10320             mProfileType = 0;
   10321         }
   10322     }
   10323 
   10324     @Override
   10325     public void setAlwaysFinish(boolean enabled) {
   10326         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   10327                 "setAlwaysFinish()");
   10328 
   10329         Settings.Global.putInt(
   10330                 mContext.getContentResolver(),
   10331                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   10332 
   10333         synchronized (this) {
   10334             mAlwaysFinishActivities = enabled;
   10335         }
   10336     }
   10337 
   10338     @Override
   10339     public void setActivityController(IActivityController controller) {
   10340         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10341                 "setActivityController()");
   10342         synchronized (this) {
   10343             mController = controller;
   10344             Watchdog.getInstance().setActivityController(controller);
   10345         }
   10346     }
   10347 
   10348     @Override
   10349     public void setUserIsMonkey(boolean userIsMonkey) {
   10350         synchronized (this) {
   10351             synchronized (mPidsSelfLocked) {
   10352                 final int callingPid = Binder.getCallingPid();
   10353                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   10354                 if (precessRecord == null) {
   10355                     throw new SecurityException("Unknown process: " + callingPid);
   10356                 }
   10357                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   10358                     throw new SecurityException("Only an instrumentation process "
   10359                             + "with a UiAutomation can call setUserIsMonkey");
   10360                 }
   10361             }
   10362             mUserIsMonkey = userIsMonkey;
   10363         }
   10364     }
   10365 
   10366     @Override
   10367     public boolean isUserAMonkey() {
   10368         synchronized (this) {
   10369             // If there is a controller also implies the user is a monkey.
   10370             return (mUserIsMonkey || mController != null);
   10371         }
   10372     }
   10373 
   10374     public void requestBugReport() {
   10375         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   10376         SystemProperties.set("ctl.start", "bugreport");
   10377     }
   10378 
   10379     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   10380         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   10381     }
   10382 
   10383     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   10384         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   10385             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   10386         }
   10387         return KEY_DISPATCHING_TIMEOUT;
   10388     }
   10389 
   10390     @Override
   10391     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   10392         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10393                 != PackageManager.PERMISSION_GRANTED) {
   10394             throw new SecurityException("Requires permission "
   10395                     + android.Manifest.permission.FILTER_EVENTS);
   10396         }
   10397         ProcessRecord proc;
   10398         long timeout;
   10399         synchronized (this) {
   10400             synchronized (mPidsSelfLocked) {
   10401                 proc = mPidsSelfLocked.get(pid);
   10402             }
   10403             timeout = getInputDispatchingTimeoutLocked(proc);
   10404         }
   10405 
   10406         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   10407             return -1;
   10408         }
   10409 
   10410         return timeout;
   10411     }
   10412 
   10413     /**
   10414      * Handle input dispatching timeouts.
   10415      * Returns whether input dispatching should be aborted or not.
   10416      */
   10417     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   10418             final ActivityRecord activity, final ActivityRecord parent,
   10419             final boolean aboveSystem, String reason) {
   10420         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   10421                 != PackageManager.PERMISSION_GRANTED) {
   10422             throw new SecurityException("Requires permission "
   10423                     + android.Manifest.permission.FILTER_EVENTS);
   10424         }
   10425 
   10426         final String annotation;
   10427         if (reason == null) {
   10428             annotation = "Input dispatching timed out";
   10429         } else {
   10430             annotation = "Input dispatching timed out (" + reason + ")";
   10431         }
   10432 
   10433         if (proc != null) {
   10434             synchronized (this) {
   10435                 if (proc.debugging) {
   10436                     return false;
   10437                 }
   10438 
   10439                 if (mDidDexOpt) {
   10440                     // Give more time since we were dexopting.
   10441                     mDidDexOpt = false;
   10442                     return false;
   10443                 }
   10444 
   10445                 if (proc.instrumentationClass != null) {
   10446                     Bundle info = new Bundle();
   10447                     info.putString("shortMsg", "keyDispatchingTimedOut");
   10448                     info.putString("longMsg", annotation);
   10449                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   10450                     return true;
   10451                 }
   10452             }
   10453             mHandler.post(new Runnable() {
   10454                 @Override
   10455                 public void run() {
   10456                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
   10457                 }
   10458             });
   10459         }
   10460 
   10461         return true;
   10462     }
   10463 
   10464     public Bundle getAssistContextExtras(int requestType) {
   10465         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
   10466                 UserHandle.getCallingUserId());
   10467         if (pae == null) {
   10468             return null;
   10469         }
   10470         synchronized (pae) {
   10471             while (!pae.haveResult) {
   10472                 try {
   10473                     pae.wait();
   10474                 } catch (InterruptedException e) {
   10475                 }
   10476             }
   10477             if (pae.result != null) {
   10478                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   10479             }
   10480         }
   10481         synchronized (this) {
   10482             mPendingAssistExtras.remove(pae);
   10483             mHandler.removeCallbacks(pae);
   10484         }
   10485         return pae.extras;
   10486     }
   10487 
   10488     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
   10489             int userHandle) {
   10490         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   10491                 "getAssistContextExtras()");
   10492         PendingAssistExtras pae;
   10493         Bundle extras = new Bundle();
   10494         synchronized (this) {
   10495             ActivityRecord activity = getFocusedStack().mResumedActivity;
   10496             if (activity == null) {
   10497                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
   10498                 return null;
   10499             }
   10500             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   10501             if (activity.app == null || activity.app.thread == null) {
   10502                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   10503                 return null;
   10504             }
   10505             if (activity.app.pid == Binder.getCallingPid()) {
   10506                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
   10507                 return null;
   10508             }
   10509             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
   10510             try {
   10511                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   10512                         requestType);
   10513                 mPendingAssistExtras.add(pae);
   10514                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
   10515             } catch (RemoteException e) {
   10516                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   10517                 return null;
   10518             }
   10519             return pae;
   10520         }
   10521     }
   10522 
   10523     public void reportAssistContextExtras(IBinder token, Bundle extras) {
   10524         PendingAssistExtras pae = (PendingAssistExtras)token;
   10525         synchronized (pae) {
   10526             pae.result = extras;
   10527             pae.haveResult = true;
   10528             pae.notifyAll();
   10529             if (pae.intent == null) {
   10530                 // Caller is just waiting for the result.
   10531                 return;
   10532             }
   10533         }
   10534 
   10535         // We are now ready to launch the assist activity.
   10536         synchronized (this) {
   10537             boolean exists = mPendingAssistExtras.remove(pae);
   10538             mHandler.removeCallbacks(pae);
   10539             if (!exists) {
   10540                 // Timed out.
   10541                 return;
   10542             }
   10543         }
   10544         pae.intent.replaceExtras(extras);
   10545         if (pae.hint != null) {
   10546             pae.intent.putExtra(pae.hint, true);
   10547         }
   10548         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
   10549                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
   10550                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
   10551         closeSystemDialogs("assist");
   10552         try {
   10553             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
   10554         } catch (ActivityNotFoundException e) {
   10555             Slog.w(TAG, "No activity to handle assist action.", e);
   10556         }
   10557     }
   10558 
   10559     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
   10560         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
   10561     }
   10562 
   10563     public void registerProcessObserver(IProcessObserver observer) {
   10564         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   10565                 "registerProcessObserver()");
   10566         synchronized (this) {
   10567             mProcessObservers.register(observer);
   10568         }
   10569     }
   10570 
   10571     @Override
   10572     public void unregisterProcessObserver(IProcessObserver observer) {
   10573         synchronized (this) {
   10574             mProcessObservers.unregister(observer);
   10575         }
   10576     }
   10577 
   10578     @Override
   10579     public boolean convertFromTranslucent(IBinder token) {
   10580         final long origId = Binder.clearCallingIdentity();
   10581         try {
   10582             synchronized (this) {
   10583                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10584                 if (r == null) {
   10585                     return false;
   10586                 }
   10587                 final boolean translucentChanged = r.changeWindowTranslucency(true);
   10588                 if (translucentChanged) {
   10589                     r.task.stack.releaseBackgroundResources();
   10590                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10591                 }
   10592                 mWindowManager.setAppFullscreen(token, true);
   10593                 return translucentChanged;
   10594             }
   10595         } finally {
   10596             Binder.restoreCallingIdentity(origId);
   10597         }
   10598     }
   10599 
   10600     @Override
   10601     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
   10602         final long origId = Binder.clearCallingIdentity();
   10603         try {
   10604             synchronized (this) {
   10605                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10606                 if (r == null) {
   10607                     return false;
   10608                 }
   10609                 int index = r.task.mActivities.lastIndexOf(r);
   10610                 if (index > 0) {
   10611                     ActivityRecord under = r.task.mActivities.get(index - 1);
   10612                     under.returningOptions = options;
   10613                 }
   10614                 final boolean translucentChanged = r.changeWindowTranslucency(false);
   10615                 if (translucentChanged) {
   10616                     r.task.stack.convertToTranslucent(r);
   10617                 }
   10618                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   10619                 mWindowManager.setAppFullscreen(token, false);
   10620                 return translucentChanged;
   10621             }
   10622         } finally {
   10623             Binder.restoreCallingIdentity(origId);
   10624         }
   10625     }
   10626 
   10627     @Override
   10628     public boolean requestVisibleBehind(IBinder token, boolean visible) {
   10629         final long origId = Binder.clearCallingIdentity();
   10630         try {
   10631             synchronized (this) {
   10632                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10633                 if (r != null) {
   10634                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
   10635                 }
   10636             }
   10637             return false;
   10638         } finally {
   10639             Binder.restoreCallingIdentity(origId);
   10640         }
   10641     }
   10642 
   10643     @Override
   10644     public boolean isBackgroundVisibleBehind(IBinder token) {
   10645         final long origId = Binder.clearCallingIdentity();
   10646         try {
   10647             synchronized (this) {
   10648                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
   10649                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
   10650                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
   10651                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
   10652                 return visible;
   10653             }
   10654         } finally {
   10655             Binder.restoreCallingIdentity(origId);
   10656         }
   10657     }
   10658 
   10659     @Override
   10660     public ActivityOptions getActivityOptions(IBinder token) {
   10661         final long origId = Binder.clearCallingIdentity();
   10662         try {
   10663             synchronized (this) {
   10664                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10665                 if (r != null) {
   10666                     final ActivityOptions activityOptions = r.pendingOptions;
   10667                     r.pendingOptions = null;
   10668                     return activityOptions;
   10669                 }
   10670                 return null;
   10671             }
   10672         } finally {
   10673             Binder.restoreCallingIdentity(origId);
   10674         }
   10675     }
   10676 
   10677     @Override
   10678     public void setImmersive(IBinder token, boolean immersive) {
   10679         synchronized(this) {
   10680             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10681             if (r == null) {
   10682                 throw new IllegalArgumentException();
   10683             }
   10684             r.immersive = immersive;
   10685 
   10686             // update associated state if we're frontmost
   10687             if (r == mFocusedActivity) {
   10688                 if (DEBUG_IMMERSIVE) {
   10689                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   10690                 }
   10691                 applyUpdateLockStateLocked(r);
   10692             }
   10693         }
   10694     }
   10695 
   10696     @Override
   10697     public boolean isImmersive(IBinder token) {
   10698         synchronized (this) {
   10699             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10700             if (r == null) {
   10701                 throw new IllegalArgumentException();
   10702             }
   10703             return r.immersive;
   10704         }
   10705     }
   10706 
   10707     public boolean isTopActivityImmersive() {
   10708         enforceNotIsolatedCaller("startActivity");
   10709         synchronized (this) {
   10710             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
   10711             return (r != null) ? r.immersive : false;
   10712         }
   10713     }
   10714 
   10715     @Override
   10716     public boolean isTopOfTask(IBinder token) {
   10717         synchronized (this) {
   10718             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   10719             if (r == null) {
   10720                 throw new IllegalArgumentException();
   10721             }
   10722             return r.task.getTopActivity() == r;
   10723         }
   10724     }
   10725 
   10726     public final void enterSafeMode() {
   10727         synchronized(this) {
   10728             // It only makes sense to do this before the system is ready
   10729             // and started launching other packages.
   10730             if (!mSystemReady) {
   10731                 try {
   10732                     AppGlobals.getPackageManager().enterSafeMode();
   10733                 } catch (RemoteException e) {
   10734                 }
   10735             }
   10736 
   10737             mSafeMode = true;
   10738         }
   10739     }
   10740 
   10741     public final void showSafeModeOverlay() {
   10742         View v = LayoutInflater.from(mContext).inflate(
   10743                 com.android.internal.R.layout.safe_mode, null);
   10744         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   10745         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   10746         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   10747         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   10748         lp.gravity = Gravity.BOTTOM | Gravity.START;
   10749         lp.format = v.getBackground().getOpacity();
   10750         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   10751                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   10752         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   10753         ((WindowManager)mContext.getSystemService(
   10754                 Context.WINDOW_SERVICE)).addView(v, lp);
   10755     }
   10756 
   10757     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
   10758         if (!(sender instanceof PendingIntentRecord)) {
   10759             return;
   10760         }
   10761         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   10762         synchronized (stats) {
   10763             if (mBatteryStatsService.isOnBattery()) {
   10764                 mBatteryStatsService.enforceCallingPermission();
   10765                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   10766                 int MY_UID = Binder.getCallingUid();
   10767                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   10768                 BatteryStatsImpl.Uid.Pkg pkg =
   10769                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
   10770                             sourcePkg != null ? sourcePkg : rec.key.packageName);
   10771                 pkg.incWakeupsLocked();
   10772             }
   10773         }
   10774     }
   10775 
   10776     public boolean killPids(int[] pids, String pReason, boolean secure) {
   10777         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10778             throw new SecurityException("killPids only available to the system");
   10779         }
   10780         String reason = (pReason == null) ? "Unknown" : pReason;
   10781         // XXX Note: don't acquire main activity lock here, because the window
   10782         // manager calls in with its locks held.
   10783 
   10784         boolean killed = false;
   10785         synchronized (mPidsSelfLocked) {
   10786             int[] types = new int[pids.length];
   10787             int worstType = 0;
   10788             for (int i=0; i<pids.length; i++) {
   10789                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10790                 if (proc != null) {
   10791                     int type = proc.setAdj;
   10792                     types[i] = type;
   10793                     if (type > worstType) {
   10794                         worstType = type;
   10795                     }
   10796                 }
   10797             }
   10798 
   10799             // If the worst oom_adj is somewhere in the cached proc LRU range,
   10800             // then constrain it so we will kill all cached procs.
   10801             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   10802                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   10803                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   10804             }
   10805 
   10806             // If this is not a secure call, don't let it kill processes that
   10807             // are important.
   10808             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   10809                 worstType = ProcessList.SERVICE_ADJ;
   10810             }
   10811 
   10812             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   10813             for (int i=0; i<pids.length; i++) {
   10814                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   10815                 if (proc == null) {
   10816                     continue;
   10817                 }
   10818                 int adj = proc.setAdj;
   10819                 if (adj >= worstType && !proc.killedByAm) {
   10820                     proc.kill(reason, true);
   10821                     killed = true;
   10822                 }
   10823             }
   10824         }
   10825         return killed;
   10826     }
   10827 
   10828     @Override
   10829     public void killUid(int uid, String reason) {
   10830         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10831             throw new SecurityException("killUid only available to the system");
   10832         }
   10833         synchronized (this) {
   10834             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   10835                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   10836                     reason != null ? reason : "kill uid");
   10837         }
   10838     }
   10839 
   10840     @Override
   10841     public boolean killProcessesBelowForeground(String reason) {
   10842         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10843             throw new SecurityException("killProcessesBelowForeground() only available to system");
   10844         }
   10845 
   10846         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   10847     }
   10848 
   10849     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   10850         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   10851             throw new SecurityException("killProcessesBelowAdj() only available to system");
   10852         }
   10853 
   10854         boolean killed = false;
   10855         synchronized (mPidsSelfLocked) {
   10856             final int size = mPidsSelfLocked.size();
   10857             for (int i = 0; i < size; i++) {
   10858                 final int pid = mPidsSelfLocked.keyAt(i);
   10859                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   10860                 if (proc == null) continue;
   10861 
   10862                 final int adj = proc.setAdj;
   10863                 if (adj > belowAdj && !proc.killedByAm) {
   10864                     proc.kill(reason, true);
   10865                     killed = true;
   10866                 }
   10867             }
   10868         }
   10869         return killed;
   10870     }
   10871 
   10872     @Override
   10873     public void hang(final IBinder who, boolean allowRestart) {
   10874         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10875                 != PackageManager.PERMISSION_GRANTED) {
   10876             throw new SecurityException("Requires permission "
   10877                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10878         }
   10879 
   10880         final IBinder.DeathRecipient death = new DeathRecipient() {
   10881             @Override
   10882             public void binderDied() {
   10883                 synchronized (this) {
   10884                     notifyAll();
   10885                 }
   10886             }
   10887         };
   10888 
   10889         try {
   10890             who.linkToDeath(death, 0);
   10891         } catch (RemoteException e) {
   10892             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   10893             return;
   10894         }
   10895 
   10896         synchronized (this) {
   10897             Watchdog.getInstance().setAllowRestart(allowRestart);
   10898             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   10899             synchronized (death) {
   10900                 while (who.isBinderAlive()) {
   10901                     try {
   10902                         death.wait();
   10903                     } catch (InterruptedException e) {
   10904                     }
   10905                 }
   10906             }
   10907             Watchdog.getInstance().setAllowRestart(true);
   10908         }
   10909     }
   10910 
   10911     @Override
   10912     public void restart() {
   10913         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10914                 != PackageManager.PERMISSION_GRANTED) {
   10915             throw new SecurityException("Requires permission "
   10916                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10917         }
   10918 
   10919         Log.i(TAG, "Sending shutdown broadcast...");
   10920 
   10921         BroadcastReceiver br = new BroadcastReceiver() {
   10922             @Override public void onReceive(Context context, Intent intent) {
   10923                 // Now the broadcast is done, finish up the low-level shutdown.
   10924                 Log.i(TAG, "Shutting down activity manager...");
   10925                 shutdown(10000);
   10926                 Log.i(TAG, "Shutdown complete, restarting!");
   10927                 Process.killProcess(Process.myPid());
   10928                 System.exit(10);
   10929             }
   10930         };
   10931 
   10932         // First send the high-level shut down broadcast.
   10933         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   10934         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   10935         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   10936         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   10937         mContext.sendOrderedBroadcastAsUser(intent,
   10938                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   10939         */
   10940         br.onReceive(mContext, intent);
   10941     }
   10942 
   10943     private long getLowRamTimeSinceIdle(long now) {
   10944         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   10945     }
   10946 
   10947     @Override
   10948     public void performIdleMaintenance() {
   10949         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   10950                 != PackageManager.PERMISSION_GRANTED) {
   10951             throw new SecurityException("Requires permission "
   10952                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   10953         }
   10954 
   10955         synchronized (this) {
   10956             final long now = SystemClock.uptimeMillis();
   10957             final long timeSinceLastIdle = now - mLastIdleTime;
   10958             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   10959             mLastIdleTime = now;
   10960             mLowRamTimeSinceLastIdle = 0;
   10961             if (mLowRamStartTime != 0) {
   10962                 mLowRamStartTime = now;
   10963             }
   10964 
   10965             StringBuilder sb = new StringBuilder(128);
   10966             sb.append("Idle maintenance over ");
   10967             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   10968             sb.append(" low RAM for ");
   10969             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   10970             Slog.i(TAG, sb.toString());
   10971 
   10972             // If at least 1/3 of our time since the last idle period has been spent
   10973             // with RAM low, then we want to kill processes.
   10974             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   10975 
   10976             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   10977                 ProcessRecord proc = mLruProcesses.get(i);
   10978                 if (proc.notCachedSinceIdle) {
   10979                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
   10980                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   10981                         if (doKilling && proc.initialIdlePss != 0
   10982                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   10983                             proc.kill("idle maint (pss " + proc.lastPss
   10984                                     + " from " + proc.initialIdlePss + ")", true);
   10985                         }
   10986                     }
   10987                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
   10988                     proc.notCachedSinceIdle = true;
   10989                     proc.initialIdlePss = 0;
   10990                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
   10991                             isSleeping(), now);
   10992                 }
   10993             }
   10994 
   10995             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   10996             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   10997         }
   10998     }
   10999 
   11000     private void retrieveSettings() {
   11001         final ContentResolver resolver = mContext.getContentResolver();
   11002         String debugApp = Settings.Global.getString(
   11003             resolver, Settings.Global.DEBUG_APP);
   11004         boolean waitForDebugger = Settings.Global.getInt(
   11005             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   11006         boolean alwaysFinishActivities = Settings.Global.getInt(
   11007             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   11008         boolean forceRtl = Settings.Global.getInt(
   11009                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
   11010         // Transfer any global setting for forcing RTL layout, into a System Property
   11011         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   11012 
   11013         Configuration configuration = new Configuration();
   11014         Settings.System.getConfiguration(resolver, configuration);
   11015         if (forceRtl) {
   11016             // This will take care of setting the correct layout direction flags
   11017             configuration.setLayoutDirection(configuration.locale);
   11018         }
   11019 
   11020         synchronized (this) {
   11021             mDebugApp = mOrigDebugApp = debugApp;
   11022             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   11023             mAlwaysFinishActivities = alwaysFinishActivities;
   11024             // This happens before any activities are started, so we can
   11025             // change mConfiguration in-place.
   11026             updateConfigurationLocked(configuration, null, false, true);
   11027             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   11028         }
   11029     }
   11030 
   11031     /** Loads resources after the current configuration has been set. */
   11032     private void loadResourcesOnSystemReady() {
   11033         final Resources res = mContext.getResources();
   11034         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
   11035         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
   11036         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
   11037     }
   11038 
   11039     public boolean testIsSystemReady() {
   11040         // no need to synchronize(this) just to read & return the value
   11041         return mSystemReady;
   11042     }
   11043 
   11044     private static File getCalledPreBootReceiversFile() {
   11045         File dataDir = Environment.getDataDirectory();
   11046         File systemDir = new File(dataDir, "system");
   11047         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
   11048         return fname;
   11049     }
   11050 
   11051     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   11052         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   11053         File file = getCalledPreBootReceiversFile();
   11054         FileInputStream fis = null;
   11055         try {
   11056             fis = new FileInputStream(file);
   11057             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   11058             int fvers = dis.readInt();
   11059             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
   11060                 String vers = dis.readUTF();
   11061                 String codename = dis.readUTF();
   11062                 String build = dis.readUTF();
   11063                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   11064                         && android.os.Build.VERSION.CODENAME.equals(codename)
   11065                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   11066                     int num = dis.readInt();
   11067                     while (num > 0) {
   11068                         num--;
   11069                         String pkg = dis.readUTF();
   11070                         String cls = dis.readUTF();
   11071                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   11072                     }
   11073                 }
   11074             }
   11075         } catch (FileNotFoundException e) {
   11076         } catch (IOException e) {
   11077             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   11078         } finally {
   11079             if (fis != null) {
   11080                 try {
   11081                     fis.close();
   11082                 } catch (IOException e) {
   11083                 }
   11084             }
   11085         }
   11086         return lastDoneReceivers;
   11087     }
   11088 
   11089     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   11090         File file = getCalledPreBootReceiversFile();
   11091         FileOutputStream fos = null;
   11092         DataOutputStream dos = null;
   11093         try {
   11094             fos = new FileOutputStream(file);
   11095             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   11096             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
   11097             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   11098             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   11099             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   11100             dos.writeInt(list.size());
   11101             for (int i=0; i<list.size(); i++) {
   11102                 dos.writeUTF(list.get(i).getPackageName());
   11103                 dos.writeUTF(list.get(i).getClassName());
   11104             }
   11105         } catch (IOException e) {
   11106             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   11107             file.delete();
   11108         } finally {
   11109             FileUtils.sync(fos);
   11110             if (dos != null) {
   11111                 try {
   11112                     dos.close();
   11113                 } catch (IOException e) {
   11114                     // TODO Auto-generated catch block
   11115                     e.printStackTrace();
   11116                 }
   11117             }
   11118         }
   11119     }
   11120 
   11121     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
   11122             ArrayList<ComponentName> doneReceivers, int userId) {
   11123         boolean waitingUpdate = false;
   11124         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   11125         List<ResolveInfo> ris = null;
   11126         try {
   11127             ris = AppGlobals.getPackageManager().queryIntentReceivers(
   11128                     intent, null, 0, userId);
   11129         } catch (RemoteException e) {
   11130         }
   11131         if (ris != null) {
   11132             for (int i=ris.size()-1; i>=0; i--) {
   11133                 if ((ris.get(i).activityInfo.applicationInfo.flags
   11134                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
   11135                     ris.remove(i);
   11136                 }
   11137             }
   11138             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   11139 
   11140             // For User 0, load the version number. When delivering to a new user, deliver
   11141             // to all receivers.
   11142             if (userId == UserHandle.USER_OWNER) {
   11143                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   11144                 for (int i=0; i<ris.size(); i++) {
   11145                     ActivityInfo ai = ris.get(i).activityInfo;
   11146                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11147                     if (lastDoneReceivers.contains(comp)) {
   11148                         // We already did the pre boot receiver for this app with the current
   11149                         // platform version, so don't do it again...
   11150                         ris.remove(i);
   11151                         i--;
   11152                         // ...however, do keep it as one that has been done, so we don't
   11153                         // forget about it when rewriting the file of last done receivers.
   11154                         doneReceivers.add(comp);
   11155                     }
   11156                 }
   11157             }
   11158 
   11159             // If primary user, send broadcast to all available users, else just to userId
   11160             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
   11161                     : new int[] { userId };
   11162             for (int i = 0; i < ris.size(); i++) {
   11163                 ActivityInfo ai = ris.get(i).activityInfo;
   11164                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
   11165                 doneReceivers.add(comp);
   11166                 intent.setComponent(comp);
   11167                 for (int j=0; j<users.length; j++) {
   11168                     IIntentReceiver finisher = null;
   11169                     // On last receiver and user, set up a completion callback
   11170                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
   11171                         finisher = new IIntentReceiver.Stub() {
   11172                             public void performReceive(Intent intent, int resultCode,
   11173                                     String data, Bundle extras, boolean ordered,
   11174                                     boolean sticky, int sendingUser) {
   11175                                 // The raw IIntentReceiver interface is called
   11176                                 // with the AM lock held, so redispatch to
   11177                                 // execute our code without the lock.
   11178                                 mHandler.post(onFinishCallback);
   11179                             }
   11180                         };
   11181                     }
   11182                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
   11183                             + " for user " + users[j]);
   11184                     broadcastIntentLocked(null, null, intent, null, finisher,
   11185                             0, null, null, null, AppOpsManager.OP_NONE,
   11186                             true, false, MY_PID, Process.SYSTEM_UID,
   11187                             users[j]);
   11188                     if (finisher != null) {
   11189                         waitingUpdate = true;
   11190                     }
   11191                 }
   11192             }
   11193         }
   11194 
   11195         return waitingUpdate;
   11196     }
   11197 
   11198     public void systemReady(final Runnable goingCallback) {
   11199         synchronized(this) {
   11200             if (mSystemReady) {
   11201                 // If we're done calling all the receivers, run the next "boot phase" passed in
   11202                 // by the SystemServer
   11203                 if (goingCallback != null) {
   11204                     goingCallback.run();
   11205                 }
   11206                 return;
   11207             }
   11208 
   11209             // Make sure we have the current profile info, since it is needed for
   11210             // security checks.
   11211             updateCurrentProfileIdsLocked();
   11212 
   11213             if (mRecentTasks == null) {
   11214                 mRecentTasks = mTaskPersister.restoreTasksLocked();
   11215                 if (!mRecentTasks.isEmpty()) {
   11216                     mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
   11217                 }
   11218                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
   11219                 mTaskPersister.startPersisting();
   11220             }
   11221 
   11222             // Check to see if there are any update receivers to run.
   11223             if (!mDidUpdate) {
   11224                 if (mWaitingUpdate) {
   11225                     return;
   11226                 }
   11227                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   11228                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
   11229                     public void run() {
   11230                         synchronized (ActivityManagerService.this) {
   11231                             mDidUpdate = true;
   11232                         }
   11233                         writeLastDonePreBootReceivers(doneReceivers);
   11234                         showBootMessage(mContext.getText(
   11235                                 R.string.android_upgrading_complete),
   11236                                 false);
   11237                         systemReady(goingCallback);
   11238                     }
   11239                 }, doneReceivers, UserHandle.USER_OWNER);
   11240 
   11241                 if (mWaitingUpdate) {
   11242                     return;
   11243                 }
   11244                 mDidUpdate = true;
   11245             }
   11246 
   11247             mAppOpsService.systemReady();
   11248             mSystemReady = true;
   11249         }
   11250 
   11251         ArrayList<ProcessRecord> procsToKill = null;
   11252         synchronized(mPidsSelfLocked) {
   11253             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   11254                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   11255                 if (!isAllowedWhileBooting(proc.info)){
   11256                     if (procsToKill == null) {
   11257                         procsToKill = new ArrayList<ProcessRecord>();
   11258                     }
   11259                     procsToKill.add(proc);
   11260                 }
   11261             }
   11262         }
   11263 
   11264         synchronized(this) {
   11265             if (procsToKill != null) {
   11266                 for (int i=procsToKill.size()-1; i>=0; i--) {
   11267                     ProcessRecord proc = procsToKill.get(i);
   11268                     Slog.i(TAG, "Removing system update proc: " + proc);
   11269                     removeProcessLocked(proc, true, false, "system update done");
   11270                 }
   11271             }
   11272 
   11273             // Now that we have cleaned up any update processes, we
   11274             // are ready to start launching real processes and know that
   11275             // we won't trample on them any more.
   11276             mProcessesReady = true;
   11277         }
   11278 
   11279         Slog.i(TAG, "System now ready");
   11280         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   11281             SystemClock.uptimeMillis());
   11282 
   11283         synchronized(this) {
   11284             // Make sure we have no pre-ready processes sitting around.
   11285 
   11286             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11287                 ResolveInfo ri = mContext.getPackageManager()
   11288                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   11289                                 STOCK_PM_FLAGS);
   11290                 CharSequence errorMsg = null;
   11291                 if (ri != null) {
   11292                     ActivityInfo ai = ri.activityInfo;
   11293                     ApplicationInfo app = ai.applicationInfo;
   11294                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   11295                         mTopAction = Intent.ACTION_FACTORY_TEST;
   11296                         mTopData = null;
   11297                         mTopComponent = new ComponentName(app.packageName,
   11298                                 ai.name);
   11299                     } else {
   11300                         errorMsg = mContext.getResources().getText(
   11301                                 com.android.internal.R.string.factorytest_not_system);
   11302                     }
   11303                 } else {
   11304                     errorMsg = mContext.getResources().getText(
   11305                             com.android.internal.R.string.factorytest_no_action);
   11306                 }
   11307                 if (errorMsg != null) {
   11308                     mTopAction = null;
   11309                     mTopData = null;
   11310                     mTopComponent = null;
   11311                     Message msg = Message.obtain();
   11312                     msg.what = SHOW_FACTORY_ERROR_MSG;
   11313                     msg.getData().putCharSequence("msg", errorMsg);
   11314                     mHandler.sendMessage(msg);
   11315                 }
   11316             }
   11317         }
   11318 
   11319         retrieveSettings();
   11320         loadResourcesOnSystemReady();
   11321 
   11322         synchronized (this) {
   11323             readGrantedUriPermissionsLocked();
   11324         }
   11325 
   11326         if (goingCallback != null) goingCallback.run();
   11327 
   11328         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
   11329                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11330         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
   11331                 Integer.toString(mCurrentUserId), mCurrentUserId);
   11332         mSystemServiceManager.startUser(mCurrentUserId);
   11333 
   11334         synchronized (this) {
   11335             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
   11336                 try {
   11337                     List apps = AppGlobals.getPackageManager().
   11338                         getPersistentApplications(STOCK_PM_FLAGS);
   11339                     if (apps != null) {
   11340                         int N = apps.size();
   11341                         int i;
   11342                         for (i=0; i<N; i++) {
   11343                             ApplicationInfo info
   11344                                 = (ApplicationInfo)apps.get(i);
   11345                             if (info != null &&
   11346                                     !info.packageName.equals("android")) {
   11347                                 addAppLocked(info, false, null /* ABI override */);
   11348                             }
   11349                         }
   11350                     }
   11351                 } catch (RemoteException ex) {
   11352                     // pm is in same process, this will never happen.
   11353                 }
   11354             }
   11355 
   11356             // Start up initial activity.
   11357             mBooting = true;
   11358             startHomeActivityLocked(mCurrentUserId);
   11359 
   11360             try {
   11361                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   11362                     Message msg = Message.obtain();
   11363                     msg.what = SHOW_UID_ERROR_MSG;
   11364                     mHandler.sendMessage(msg);
   11365                 }
   11366             } catch (RemoteException e) {
   11367             }
   11368 
   11369             long ident = Binder.clearCallingIdentity();
   11370             try {
   11371                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   11372                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   11373                         | Intent.FLAG_RECEIVER_FOREGROUND);
   11374                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11375                 broadcastIntentLocked(null, null, intent,
   11376                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   11377                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   11378                 intent = new Intent(Intent.ACTION_USER_STARTING);
   11379                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   11380                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   11381                 broadcastIntentLocked(null, null, intent,
   11382                         null, new IIntentReceiver.Stub() {
   11383                             @Override
   11384                             public void performReceive(Intent intent, int resultCode, String data,
   11385                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   11386                                     throws RemoteException {
   11387                             }
   11388                         }, 0, null, null,
   11389                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   11390                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   11391             } catch (Throwable t) {
   11392                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
   11393             } finally {
   11394                 Binder.restoreCallingIdentity(ident);
   11395             }
   11396             mStackSupervisor.resumeTopActivitiesLocked();
   11397             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   11398         }
   11399     }
   11400 
   11401     private boolean makeAppCrashingLocked(ProcessRecord app,
   11402             String shortMsg, String longMsg, String stackTrace) {
   11403         app.crashing = true;
   11404         app.crashingReport = generateProcessError(app,
   11405                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   11406         startAppProblemLocked(app);
   11407         app.stopFreezingAllLocked();
   11408         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
   11409     }
   11410 
   11411     private void makeAppNotRespondingLocked(ProcessRecord app,
   11412             String activity, String shortMsg, String longMsg) {
   11413         app.notResponding = true;
   11414         app.notRespondingReport = generateProcessError(app,
   11415                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   11416                 activity, shortMsg, longMsg, null);
   11417         startAppProblemLocked(app);
   11418         app.stopFreezingAllLocked();
   11419     }
   11420 
   11421     /**
   11422      * Generate a process error record, suitable for attachment to a ProcessRecord.
   11423      *
   11424      * @param app The ProcessRecord in which the error occurred.
   11425      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   11426      *                      ActivityManager.AppErrorStateInfo
   11427      * @param activity The activity associated with the crash, if known.
   11428      * @param shortMsg Short message describing the crash.
   11429      * @param longMsg Long message describing the crash.
   11430      * @param stackTrace Full crash stack trace, may be null.
   11431      *
   11432      * @return Returns a fully-formed AppErrorStateInfo record.
   11433      */
   11434     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   11435             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   11436         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   11437 
   11438         report.condition = condition;
   11439         report.processName = app.processName;
   11440         report.pid = app.pid;
   11441         report.uid = app.info.uid;
   11442         report.tag = activity;
   11443         report.shortMsg = shortMsg;
   11444         report.longMsg = longMsg;
   11445         report.stackTrace = stackTrace;
   11446 
   11447         return report;
   11448     }
   11449 
   11450     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   11451         synchronized (this) {
   11452             app.crashing = false;
   11453             app.crashingReport = null;
   11454             app.notResponding = false;
   11455             app.notRespondingReport = null;
   11456             if (app.anrDialog == fromDialog) {
   11457                 app.anrDialog = null;
   11458             }
   11459             if (app.waitDialog == fromDialog) {
   11460                 app.waitDialog = null;
   11461             }
   11462             if (app.pid > 0 && app.pid != MY_PID) {
   11463                 handleAppCrashLocked(app, null, null, null);
   11464                 app.kill("user request after error", true);
   11465             }
   11466         }
   11467     }
   11468 
   11469     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
   11470             String stackTrace) {
   11471         long now = SystemClock.uptimeMillis();
   11472 
   11473         Long crashTime;
   11474         if (!app.isolated) {
   11475             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   11476         } else {
   11477             crashTime = null;
   11478         }
   11479         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   11480             // This process loses!
   11481             Slog.w(TAG, "Process " + app.info.processName
   11482                     + " has crashed too many times: killing!");
   11483             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   11484                     app.userId, app.info.processName, app.uid);
   11485             mStackSupervisor.handleAppCrashLocked(app);
   11486             if (!app.persistent) {
   11487                 // We don't want to start this process again until the user
   11488                 // explicitly does so...  but for persistent process, we really
   11489                 // need to keep it running.  If a persistent process is actually
   11490                 // repeatedly crashing, then badness for everyone.
   11491                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   11492                         app.info.processName);
   11493                 if (!app.isolated) {
   11494                     // XXX We don't have a way to mark isolated processes
   11495                     // as bad, since they don't have a peristent identity.
   11496                     mBadProcesses.put(app.info.processName, app.uid,
   11497                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
   11498                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   11499                 }
   11500                 app.bad = true;
   11501                 app.removed = true;
   11502                 // Don't let services in this process be restarted and potentially
   11503                 // annoy the user repeatedly.  Unless it is persistent, since those
   11504                 // processes run critical code.
   11505                 removeProcessLocked(app, false, false, "crash");
   11506                 mStackSupervisor.resumeTopActivitiesLocked();
   11507                 return false;
   11508             }
   11509             mStackSupervisor.resumeTopActivitiesLocked();
   11510         } else {
   11511             mStackSupervisor.finishTopRunningActivityLocked(app);
   11512         }
   11513 
   11514         // Bump up the crash count of any services currently running in the proc.
   11515         for (int i=app.services.size()-1; i>=0; i--) {
   11516             // Any services running in the application need to be placed
   11517             // back in the pending list.
   11518             ServiceRecord sr = app.services.valueAt(i);
   11519             sr.crashCount++;
   11520         }
   11521 
   11522         // If the crashing process is what we consider to be the "home process" and it has been
   11523         // replaced by a third-party app, clear the package preferred activities from packages
   11524         // with a home activity running in the process to prevent a repeatedly crashing app
   11525         // from blocking the user to manually clear the list.
   11526         final ArrayList<ActivityRecord> activities = app.activities;
   11527         if (app == mHomeProcess && activities.size() > 0
   11528                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   11529             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   11530                 final ActivityRecord r = activities.get(activityNdx);
   11531                 if (r.isHomeActivity()) {
   11532                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   11533                     try {
   11534                         ActivityThread.getPackageManager()
   11535                                 .clearPackagePreferredActivities(r.packageName);
   11536                     } catch (RemoteException c) {
   11537                         // pm is in same process, this will never happen.
   11538                     }
   11539                 }
   11540             }
   11541         }
   11542 
   11543         if (!app.isolated) {
   11544             // XXX Can't keep track of crash times for isolated processes,
   11545             // because they don't have a perisistent identity.
   11546             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   11547         }
   11548 
   11549         if (app.crashHandler != null) mHandler.post(app.crashHandler);
   11550         return true;
   11551     }
   11552 
   11553     void startAppProblemLocked(ProcessRecord app) {
   11554         // If this app is not running under the current user, then we
   11555         // can't give it a report button because that would require
   11556         // launching the report UI under a different user.
   11557         app.errorReportReceiver = null;
   11558 
   11559         for (int userId : mCurrentProfileIds) {
   11560             if (app.userId == userId) {
   11561                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   11562                         mContext, app.info.packageName, app.info.flags);
   11563             }
   11564         }
   11565         skipCurrentReceiverLocked(app);
   11566     }
   11567 
   11568     void skipCurrentReceiverLocked(ProcessRecord app) {
   11569         for (BroadcastQueue queue : mBroadcastQueues) {
   11570             queue.skipCurrentReceiverLocked(app);
   11571         }
   11572     }
   11573 
   11574     /**
   11575      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   11576      * The application process will exit immediately after this call returns.
   11577      * @param app object of the crashing app, null for the system server
   11578      * @param crashInfo describing the exception
   11579      */
   11580     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   11581         ProcessRecord r = findAppProcess(app, "Crash");
   11582         final String processName = app == null ? "system_server"
   11583                 : (r == null ? "unknown" : r.processName);
   11584 
   11585         handleApplicationCrashInner("crash", r, processName, crashInfo);
   11586     }
   11587 
   11588     /* Native crash reporting uses this inner version because it needs to be somewhat
   11589      * decoupled from the AM-managed cleanup lifecycle
   11590      */
   11591     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   11592             ApplicationErrorReport.CrashInfo crashInfo) {
   11593         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   11594                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   11595                 r == null ? -1 : r.info.flags,
   11596                 crashInfo.exceptionClassName,
   11597                 crashInfo.exceptionMessage,
   11598                 crashInfo.throwFileName,
   11599                 crashInfo.throwLineNumber);
   11600 
   11601         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   11602 
   11603         crashApplication(r, crashInfo);
   11604     }
   11605 
   11606     public void handleApplicationStrictModeViolation(
   11607             IBinder app,
   11608             int violationMask,
   11609             StrictMode.ViolationInfo info) {
   11610         ProcessRecord r = findAppProcess(app, "StrictMode");
   11611         if (r == null) {
   11612             return;
   11613         }
   11614 
   11615         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   11616             Integer stackFingerprint = info.hashCode();
   11617             boolean logIt = true;
   11618             synchronized (mAlreadyLoggedViolatedStacks) {
   11619                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   11620                     logIt = false;
   11621                     // TODO: sub-sample into EventLog for these, with
   11622                     // the info.durationMillis?  Then we'd get
   11623                     // the relative pain numbers, without logging all
   11624                     // the stack traces repeatedly.  We'd want to do
   11625                     // likewise in the client code, which also does
   11626                     // dup suppression, before the Binder call.
   11627                 } else {
   11628                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   11629                         mAlreadyLoggedViolatedStacks.clear();
   11630                     }
   11631                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   11632                 }
   11633             }
   11634             if (logIt) {
   11635                 logStrictModeViolationToDropBox(r, info);
   11636             }
   11637         }
   11638 
   11639         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   11640             AppErrorResult result = new AppErrorResult();
   11641             synchronized (this) {
   11642                 final long origId = Binder.clearCallingIdentity();
   11643 
   11644                 Message msg = Message.obtain();
   11645                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   11646                 HashMap<String, Object> data = new HashMap<String, Object>();
   11647                 data.put("result", result);
   11648                 data.put("app", r);
   11649                 data.put("violationMask", violationMask);
   11650                 data.put("info", info);
   11651                 msg.obj = data;
   11652                 mHandler.sendMessage(msg);
   11653 
   11654                 Binder.restoreCallingIdentity(origId);
   11655             }
   11656             int res = result.get();
   11657             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   11658         }
   11659     }
   11660 
   11661     // Depending on the policy in effect, there could be a bunch of
   11662     // these in quick succession so we try to batch these together to
   11663     // minimize disk writes, number of dropbox entries, and maximize
   11664     // compression, by having more fewer, larger records.
   11665     private void logStrictModeViolationToDropBox(
   11666             ProcessRecord process,
   11667             StrictMode.ViolationInfo info) {
   11668         if (info == null) {
   11669             return;
   11670         }
   11671         final boolean isSystemApp = process == null ||
   11672                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   11673                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   11674         final String processName = process == null ? "unknown" : process.processName;
   11675         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   11676         final DropBoxManager dbox = (DropBoxManager)
   11677                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11678 
   11679         // Exit early if the dropbox isn't configured to accept this report type.
   11680         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11681 
   11682         boolean bufferWasEmpty;
   11683         boolean needsFlush;
   11684         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   11685         synchronized (sb) {
   11686             bufferWasEmpty = sb.length() == 0;
   11687             appendDropBoxProcessHeaders(process, processName, sb);
   11688             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11689             sb.append("System-App: ").append(isSystemApp).append("\n");
   11690             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   11691             if (info.violationNumThisLoop != 0) {
   11692                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   11693             }
   11694             if (info.numAnimationsRunning != 0) {
   11695                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   11696             }
   11697             if (info.broadcastIntentAction != null) {
   11698                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   11699             }
   11700             if (info.durationMillis != -1) {
   11701                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   11702             }
   11703             if (info.numInstances != -1) {
   11704                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   11705             }
   11706             if (info.tags != null) {
   11707                 for (String tag : info.tags) {
   11708                     sb.append("Span-Tag: ").append(tag).append("\n");
   11709                 }
   11710             }
   11711             sb.append("\n");
   11712             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   11713                 sb.append(info.crashInfo.stackTrace);
   11714             }
   11715             sb.append("\n");
   11716 
   11717             // Only buffer up to ~64k.  Various logging bits truncate
   11718             // things at 128k.
   11719             needsFlush = (sb.length() > 64 * 1024);
   11720         }
   11721 
   11722         // Flush immediately if the buffer's grown too large, or this
   11723         // is a non-system app.  Non-system apps are isolated with a
   11724         // different tag & policy and not batched.
   11725         //
   11726         // Batching is useful during internal testing with
   11727         // StrictMode settings turned up high.  Without batching,
   11728         // thousands of separate files could be created on boot.
   11729         if (!isSystemApp || needsFlush) {
   11730             new Thread("Error dump: " + dropboxTag) {
   11731                 @Override
   11732                 public void run() {
   11733                     String report;
   11734                     synchronized (sb) {
   11735                         report = sb.toString();
   11736                         sb.delete(0, sb.length());
   11737                         sb.trimToSize();
   11738                     }
   11739                     if (report.length() != 0) {
   11740                         dbox.addText(dropboxTag, report);
   11741                     }
   11742                 }
   11743             }.start();
   11744             return;
   11745         }
   11746 
   11747         // System app batching:
   11748         if (!bufferWasEmpty) {
   11749             // An existing dropbox-writing thread is outstanding, so
   11750             // we don't need to start it up.  The existing thread will
   11751             // catch the buffer appends we just did.
   11752             return;
   11753         }
   11754 
   11755         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   11756         // (After this point, we shouldn't access AMS internal data structures.)
   11757         new Thread("Error dump: " + dropboxTag) {
   11758             @Override
   11759             public void run() {
   11760                 // 5 second sleep to let stacks arrive and be batched together
   11761                 try {
   11762                     Thread.sleep(5000);  // 5 seconds
   11763                 } catch (InterruptedException e) {}
   11764 
   11765                 String errorReport;
   11766                 synchronized (mStrictModeBuffer) {
   11767                     errorReport = mStrictModeBuffer.toString();
   11768                     if (errorReport.length() == 0) {
   11769                         return;
   11770                     }
   11771                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   11772                     mStrictModeBuffer.trimToSize();
   11773                 }
   11774                 dbox.addText(dropboxTag, errorReport);
   11775             }
   11776         }.start();
   11777     }
   11778 
   11779     /**
   11780      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   11781      * @param app object of the crashing app, null for the system server
   11782      * @param tag reported by the caller
   11783      * @param system whether this wtf is coming from the system
   11784      * @param crashInfo describing the context of the error
   11785      * @return true if the process should exit immediately (WTF is fatal)
   11786      */
   11787     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
   11788             final ApplicationErrorReport.CrashInfo crashInfo) {
   11789         final int callingUid = Binder.getCallingUid();
   11790         final int callingPid = Binder.getCallingPid();
   11791 
   11792         if (system) {
   11793             // If this is coming from the system, we could very well have low-level
   11794             // system locks held, so we want to do this all asynchronously.  And we
   11795             // never want this to become fatal, so there is that too.
   11796             mHandler.post(new Runnable() {
   11797                 @Override public void run() {
   11798                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
   11799                 }
   11800             });
   11801             return false;
   11802         }
   11803 
   11804         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
   11805                 crashInfo);
   11806 
   11807         if (r != null && r.pid != Process.myPid() &&
   11808                 Settings.Global.getInt(mContext.getContentResolver(),
   11809                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   11810             crashApplication(r, crashInfo);
   11811             return true;
   11812         } else {
   11813             return false;
   11814         }
   11815     }
   11816 
   11817     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
   11818             final ApplicationErrorReport.CrashInfo crashInfo) {
   11819         final ProcessRecord r = findAppProcess(app, "WTF");
   11820         final String processName = app == null ? "system_server"
   11821                 : (r == null ? "unknown" : r.processName);
   11822 
   11823         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
   11824                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
   11825 
   11826         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   11827 
   11828         return r;
   11829     }
   11830 
   11831     /**
   11832      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   11833      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   11834      */
   11835     private ProcessRecord findAppProcess(IBinder app, String reason) {
   11836         if (app == null) {
   11837             return null;
   11838         }
   11839 
   11840         synchronized (this) {
   11841             final int NP = mProcessNames.getMap().size();
   11842             for (int ip=0; ip<NP; ip++) {
   11843                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   11844                 final int NA = apps.size();
   11845                 for (int ia=0; ia<NA; ia++) {
   11846                     ProcessRecord p = apps.valueAt(ia);
   11847                     if (p.thread != null && p.thread.asBinder() == app) {
   11848                         return p;
   11849                     }
   11850                 }
   11851             }
   11852 
   11853             Slog.w(TAG, "Can't find mystery application for " + reason
   11854                     + " from pid=" + Binder.getCallingPid()
   11855                     + " uid=" + Binder.getCallingUid() + ": " + app);
   11856             return null;
   11857         }
   11858     }
   11859 
   11860     /**
   11861      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   11862      * to append various headers to the dropbox log text.
   11863      */
   11864     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   11865             StringBuilder sb) {
   11866         // Watchdog thread ends up invoking this function (with
   11867         // a null ProcessRecord) to add the stack file to dropbox.
   11868         // Do not acquire a lock on this (am) in such cases, as it
   11869         // could cause a potential deadlock, if and when watchdog
   11870         // is invoked due to unavailability of lock on am and it
   11871         // would prevent watchdog from killing system_server.
   11872         if (process == null) {
   11873             sb.append("Process: ").append(processName).append("\n");
   11874             return;
   11875         }
   11876         // Note: ProcessRecord 'process' is guarded by the service
   11877         // instance.  (notably process.pkgList, which could otherwise change
   11878         // concurrently during execution of this method)
   11879         synchronized (this) {
   11880             sb.append("Process: ").append(processName).append("\n");
   11881             int flags = process.info.flags;
   11882             IPackageManager pm = AppGlobals.getPackageManager();
   11883             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   11884             for (int ip=0; ip<process.pkgList.size(); ip++) {
   11885                 String pkg = process.pkgList.keyAt(ip);
   11886                 sb.append("Package: ").append(pkg);
   11887                 try {
   11888                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   11889                     if (pi != null) {
   11890                         sb.append(" v").append(pi.versionCode);
   11891                         if (pi.versionName != null) {
   11892                             sb.append(" (").append(pi.versionName).append(")");
   11893                         }
   11894                     }
   11895                 } catch (RemoteException e) {
   11896                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   11897                 }
   11898                 sb.append("\n");
   11899             }
   11900         }
   11901     }
   11902 
   11903     private static String processClass(ProcessRecord process) {
   11904         if (process == null || process.pid == MY_PID) {
   11905             return "system_server";
   11906         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   11907             return "system_app";
   11908         } else {
   11909             return "data_app";
   11910         }
   11911     }
   11912 
   11913     /**
   11914      * Write a description of an error (crash, WTF, ANR) to the drop box.
   11915      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   11916      * @param process which caused the error, null means the system server
   11917      * @param activity which triggered the error, null if unknown
   11918      * @param parent activity related to the error, null if unknown
   11919      * @param subject line related to the error, null if absent
   11920      * @param report in long form describing the error, null if absent
   11921      * @param logFile to include in the report, null if none
   11922      * @param crashInfo giving an application stack trace, null if absent
   11923      */
   11924     public void addErrorToDropBox(String eventType,
   11925             ProcessRecord process, String processName, ActivityRecord activity,
   11926             ActivityRecord parent, String subject,
   11927             final String report, final File logFile,
   11928             final ApplicationErrorReport.CrashInfo crashInfo) {
   11929         // NOTE -- this must never acquire the ActivityManagerService lock,
   11930         // otherwise the watchdog may be prevented from resetting the system.
   11931 
   11932         final String dropboxTag = processClass(process) + "_" + eventType;
   11933         final DropBoxManager dbox = (DropBoxManager)
   11934                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   11935 
   11936         // Exit early if the dropbox isn't configured to accept this report type.
   11937         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   11938 
   11939         final StringBuilder sb = new StringBuilder(1024);
   11940         appendDropBoxProcessHeaders(process, processName, sb);
   11941         if (activity != null) {
   11942             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   11943         }
   11944         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   11945             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   11946         }
   11947         if (parent != null && parent != activity) {
   11948             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   11949         }
   11950         if (subject != null) {
   11951             sb.append("Subject: ").append(subject).append("\n");
   11952         }
   11953         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   11954         if (Debug.isDebuggerConnected()) {
   11955             sb.append("Debugger: Connected\n");
   11956         }
   11957         sb.append("\n");
   11958 
   11959         // Do the rest in a worker thread to avoid blocking the caller on I/O
   11960         // (After this point, we shouldn't access AMS internal data structures.)
   11961         Thread worker = new Thread("Error dump: " + dropboxTag) {
   11962             @Override
   11963             public void run() {
   11964                 if (report != null) {
   11965                     sb.append(report);
   11966                 }
   11967                 if (logFile != null) {
   11968                     try {
   11969                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
   11970                                     "\n\n[[TRUNCATED]]"));
   11971                     } catch (IOException e) {
   11972                         Slog.e(TAG, "Error reading " + logFile, e);
   11973                     }
   11974                 }
   11975                 if (crashInfo != null && crashInfo.stackTrace != null) {
   11976                     sb.append(crashInfo.stackTrace);
   11977                 }
   11978 
   11979                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   11980                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   11981                 if (lines > 0) {
   11982                     sb.append("\n");
   11983 
   11984                     // Merge several logcat streams, and take the last N lines
   11985                     InputStreamReader input = null;
   11986                     try {
   11987                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   11988                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   11989                                 "-b", "crash",
   11990                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   11991 
   11992                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   11993                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   11994                         input = new InputStreamReader(logcat.getInputStream());
   11995 
   11996                         int num;
   11997                         char[] buf = new char[8192];
   11998                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   11999                     } catch (IOException e) {
   12000                         Slog.e(TAG, "Error running logcat", e);
   12001                     } finally {
   12002                         if (input != null) try { input.close(); } catch (IOException e) {}
   12003                     }
   12004                 }
   12005 
   12006                 dbox.addText(dropboxTag, sb.toString());
   12007             }
   12008         };
   12009 
   12010         if (process == null) {
   12011             // If process is null, we are being called from some internal code
   12012             // and may be about to die -- run this synchronously.
   12013             worker.run();
   12014         } else {
   12015             worker.start();
   12016         }
   12017     }
   12018 
   12019     /**
   12020      * Bring up the "unexpected error" dialog box for a crashing app.
   12021      * Deal with edge cases (intercepts from instrumented applications,
   12022      * ActivityController, error intent receivers, that sort of thing).
   12023      * @param r the application crashing
   12024      * @param crashInfo describing the failure
   12025      */
   12026     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   12027         long timeMillis = System.currentTimeMillis();
   12028         String shortMsg = crashInfo.exceptionClassName;
   12029         String longMsg = crashInfo.exceptionMessage;
   12030         String stackTrace = crashInfo.stackTrace;
   12031         if (shortMsg != null && longMsg != null) {
   12032             longMsg = shortMsg + ": " + longMsg;
   12033         } else if (shortMsg != null) {
   12034             longMsg = shortMsg;
   12035         }
   12036 
   12037         AppErrorResult result = new AppErrorResult();
   12038         synchronized (this) {
   12039             if (mController != null) {
   12040                 try {
   12041                     String name = r != null ? r.processName : null;
   12042                     int pid = r != null ? r.pid : Binder.getCallingPid();
   12043                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
   12044                     if (!mController.appCrashed(name, pid,
   12045                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   12046                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
   12047                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
   12048                             Slog.w(TAG, "Skip killing native crashed app " + name
   12049                                     + "(" + pid + ") during testing");
   12050                         } else {
   12051                             Slog.w(TAG, "Force-killing crashed app " + name
   12052                                     + " at watcher's request");
   12053                             if (r != null) {
   12054                                 r.kill("crash", true);
   12055                             } else {
   12056                                 // Huh.
   12057                                 Process.killProcess(pid);
   12058                                 Process.killProcessGroup(uid, pid);
   12059                             }
   12060                         }
   12061                         return;
   12062                     }
   12063                 } catch (RemoteException e) {
   12064                     mController = null;
   12065                     Watchdog.getInstance().setActivityController(null);
   12066                 }
   12067             }
   12068 
   12069             final long origId = Binder.clearCallingIdentity();
   12070 
   12071             // If this process is running instrumentation, finish it.
   12072             if (r != null && r.instrumentationClass != null) {
   12073                 Slog.w(TAG, "Error in app " + r.processName
   12074                       + " running instrumentation " + r.instrumentationClass + ":");
   12075                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   12076                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   12077                 Bundle info = new Bundle();
   12078                 info.putString("shortMsg", shortMsg);
   12079                 info.putString("longMsg", longMsg);
   12080                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   12081                 Binder.restoreCallingIdentity(origId);
   12082                 return;
   12083             }
   12084 
   12085             // If we can't identify the process or it's already exceeded its crash quota,
   12086             // quit right away without showing a crash dialog.
   12087             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   12088                 Binder.restoreCallingIdentity(origId);
   12089                 return;
   12090             }
   12091 
   12092             Message msg = Message.obtain();
   12093             msg.what = SHOW_ERROR_MSG;
   12094             HashMap data = new HashMap();
   12095             data.put("result", result);
   12096             data.put("app", r);
   12097             msg.obj = data;
   12098             mHandler.sendMessage(msg);
   12099 
   12100             Binder.restoreCallingIdentity(origId);
   12101         }
   12102 
   12103         int res = result.get();
   12104 
   12105         Intent appErrorIntent = null;
   12106         synchronized (this) {
   12107             if (r != null && !r.isolated) {
   12108                 // XXX Can't keep track of crash time for isolated processes,
   12109                 // since they don't have a persistent identity.
   12110                 mProcessCrashTimes.put(r.info.processName, r.uid,
   12111                         SystemClock.uptimeMillis());
   12112             }
   12113             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   12114                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   12115             }
   12116         }
   12117 
   12118         if (appErrorIntent != null) {
   12119             try {
   12120                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   12121             } catch (ActivityNotFoundException e) {
   12122                 Slog.w(TAG, "bug report receiver dissappeared", e);
   12123             }
   12124         }
   12125     }
   12126 
   12127     Intent createAppErrorIntentLocked(ProcessRecord r,
   12128             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12129         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   12130         if (report == null) {
   12131             return null;
   12132         }
   12133         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   12134         result.setComponent(r.errorReportReceiver);
   12135         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   12136         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   12137         return result;
   12138     }
   12139 
   12140     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   12141             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   12142         if (r.errorReportReceiver == null) {
   12143             return null;
   12144         }
   12145 
   12146         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   12147             return null;
   12148         }
   12149 
   12150         ApplicationErrorReport report = new ApplicationErrorReport();
   12151         report.packageName = r.info.packageName;
   12152         report.installerPackageName = r.errorReportReceiver.getPackageName();
   12153         report.processName = r.processName;
   12154         report.time = timeMillis;
   12155         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   12156 
   12157         if (r.crashing || r.forceCrashReport) {
   12158             report.type = ApplicationErrorReport.TYPE_CRASH;
   12159             report.crashInfo = crashInfo;
   12160         } else if (r.notResponding) {
   12161             report.type = ApplicationErrorReport.TYPE_ANR;
   12162             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   12163 
   12164             report.anrInfo.activity = r.notRespondingReport.tag;
   12165             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   12166             report.anrInfo.info = r.notRespondingReport.longMsg;
   12167         }
   12168 
   12169         return report;
   12170     }
   12171 
   12172     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   12173         enforceNotIsolatedCaller("getProcessesInErrorState");
   12174         // assume our apps are happy - lazy create the list
   12175         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   12176 
   12177         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12178                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   12179         int userId = UserHandle.getUserId(Binder.getCallingUid());
   12180 
   12181         synchronized (this) {
   12182 
   12183             // iterate across all processes
   12184             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12185                 ProcessRecord app = mLruProcesses.get(i);
   12186                 if (!allUsers && app.userId != userId) {
   12187                     continue;
   12188                 }
   12189                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   12190                     // This one's in trouble, so we'll generate a report for it
   12191                     // crashes are higher priority (in case there's a crash *and* an anr)
   12192                     ActivityManager.ProcessErrorStateInfo report = null;
   12193                     if (app.crashing) {
   12194                         report = app.crashingReport;
   12195                     } else if (app.notResponding) {
   12196                         report = app.notRespondingReport;
   12197                     }
   12198 
   12199                     if (report != null) {
   12200                         if (errList == null) {
   12201                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   12202                         }
   12203                         errList.add(report);
   12204                     } else {
   12205                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   12206                                 " crashing = " + app.crashing +
   12207                                 " notResponding = " + app.notResponding);
   12208                     }
   12209                 }
   12210             }
   12211         }
   12212 
   12213         return errList;
   12214     }
   12215 
   12216     static int procStateToImportance(int procState, int memAdj,
   12217             ActivityManager.RunningAppProcessInfo currApp) {
   12218         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
   12219         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
   12220             currApp.lru = memAdj;
   12221         } else {
   12222             currApp.lru = 0;
   12223         }
   12224         return imp;
   12225     }
   12226 
   12227     private void fillInProcMemInfo(ProcessRecord app,
   12228             ActivityManager.RunningAppProcessInfo outInfo) {
   12229         outInfo.pid = app.pid;
   12230         outInfo.uid = app.info.uid;
   12231         if (mHeavyWeightProcess == app) {
   12232             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   12233         }
   12234         if (app.persistent) {
   12235             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   12236         }
   12237         if (app.activities.size() > 0) {
   12238             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   12239         }
   12240         outInfo.lastTrimLevel = app.trimMemoryLevel;
   12241         int adj = app.curAdj;
   12242         int procState = app.curProcState;
   12243         outInfo.importance = procStateToImportance(procState, adj, outInfo);
   12244         outInfo.importanceReasonCode = app.adjTypeCode;
   12245         outInfo.processState = app.curProcState;
   12246     }
   12247 
   12248     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   12249         enforceNotIsolatedCaller("getRunningAppProcesses");
   12250         // Lazy instantiation of list
   12251         List<ActivityManager.RunningAppProcessInfo> runList = null;
   12252         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
   12253                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   12254         int userId = UserHandle.getUserId(Binder.getCallingUid());
   12255         synchronized (this) {
   12256             // Iterate across all processes
   12257             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   12258                 ProcessRecord app = mLruProcesses.get(i);
   12259                 if (!allUsers && app.userId != userId) {
   12260                     continue;
   12261                 }
   12262                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   12263                     // Generate process state info for running application
   12264                     ActivityManager.RunningAppProcessInfo currApp =
   12265                         new ActivityManager.RunningAppProcessInfo(app.processName,
   12266                                 app.pid, app.getPackageList());
   12267                     fillInProcMemInfo(app, currApp);
   12268                     if (app.adjSource instanceof ProcessRecord) {
   12269                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   12270                         currApp.importanceReasonImportance =
   12271                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
   12272                                         app.adjSourceProcState);
   12273                     } else if (app.adjSource instanceof ActivityRecord) {
   12274                         ActivityRecord r = (ActivityRecord)app.adjSource;
   12275                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   12276                     }
   12277                     if (app.adjTarget instanceof ComponentName) {
   12278                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   12279                     }
   12280                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   12281                     //        + " lru=" + currApp.lru);
   12282                     if (runList == null) {
   12283                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   12284                     }
   12285                     runList.add(currApp);
   12286                 }
   12287             }
   12288         }
   12289         return runList;
   12290     }
   12291 
   12292     public List<ApplicationInfo> getRunningExternalApplications() {
   12293         enforceNotIsolatedCaller("getRunningExternalApplications");
   12294         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   12295         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   12296         if (runningApps != null && runningApps.size() > 0) {
   12297             Set<String> extList = new HashSet<String>();
   12298             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   12299                 if (app.pkgList != null) {
   12300                     for (String pkg : app.pkgList) {
   12301                         extList.add(pkg);
   12302                     }
   12303                 }
   12304             }
   12305             IPackageManager pm = AppGlobals.getPackageManager();
   12306             for (String pkg : extList) {
   12307                 try {
   12308                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   12309                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   12310                         retList.add(info);
   12311                     }
   12312                 } catch (RemoteException e) {
   12313                 }
   12314             }
   12315         }
   12316         return retList;
   12317     }
   12318 
   12319     @Override
   12320     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   12321         enforceNotIsolatedCaller("getMyMemoryState");
   12322         synchronized (this) {
   12323             ProcessRecord proc;
   12324             synchronized (mPidsSelfLocked) {
   12325                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   12326             }
   12327             fillInProcMemInfo(proc, outInfo);
   12328         }
   12329     }
   12330 
   12331     @Override
   12332     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   12333         if (checkCallingPermission(android.Manifest.permission.DUMP)
   12334                 != PackageManager.PERMISSION_GRANTED) {
   12335             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   12336                     + Binder.getCallingPid()
   12337                     + ", uid=" + Binder.getCallingUid()
   12338                     + " without permission "
   12339                     + android.Manifest.permission.DUMP);
   12340             return;
   12341         }
   12342 
   12343         boolean dumpAll = false;
   12344         boolean dumpClient = false;
   12345         String dumpPackage = null;
   12346 
   12347         int opti = 0;
   12348         while (opti < args.length) {
   12349             String opt = args[opti];
   12350             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   12351                 break;
   12352             }
   12353             opti++;
   12354             if ("-a".equals(opt)) {
   12355                 dumpAll = true;
   12356             } else if ("-c".equals(opt)) {
   12357                 dumpClient = true;
   12358             } else if ("-h".equals(opt)) {
   12359                 pw.println("Activity manager dump options:");
   12360                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   12361                 pw.println("  cmd may be one of:");
   12362                 pw.println("    a[ctivities]: activity stack state");
   12363                 pw.println("    r[recents]: recent activities state");
   12364                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   12365                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   12366                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   12367                 pw.println("    o[om]: out of memory management");
   12368                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   12369                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   12370                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   12371                 pw.println("    service [COMP_SPEC]: service client-side state");
   12372                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   12373                 pw.println("    all: dump all activities");
   12374                 pw.println("    top: dump the top activity");
   12375                 pw.println("    write: write all pending state to storage");
   12376                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   12377                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   12378                 pw.println("    a partial substring in a component name, a");
   12379                 pw.println("    hex object identifier.");
   12380                 pw.println("  -a: include all available server state.");
   12381                 pw.println("  -c: include client state.");
   12382                 return;
   12383             } else {
   12384                 pw.println("Unknown argument: " + opt + "; use -h for help");
   12385             }
   12386         }
   12387 
   12388         long origId = Binder.clearCallingIdentity();
   12389         boolean more = false;
   12390         // Is the caller requesting to dump a particular piece of data?
   12391         if (opti < args.length) {
   12392             String cmd = args[opti];
   12393             opti++;
   12394             if ("activities".equals(cmd) || "a".equals(cmd)) {
   12395                 synchronized (this) {
   12396                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   12397                 }
   12398             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
   12399                 synchronized (this) {
   12400                     dumpRecentsLocked(fd, pw, args, opti, true, null);
   12401                 }
   12402             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   12403                 String[] newArgs;
   12404                 String name;
   12405                 if (opti >= args.length) {
   12406                     name = null;
   12407                     newArgs = EMPTY_STRING_ARRAY;
   12408                 } else {
   12409                     name = args[opti];
   12410                     opti++;
   12411                     newArgs = new String[args.length - opti];
   12412                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12413                             args.length - opti);
   12414                 }
   12415                 synchronized (this) {
   12416                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   12417                 }
   12418             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   12419                 String[] newArgs;
   12420                 String name;
   12421                 if (opti >= args.length) {
   12422                     name = null;
   12423                     newArgs = EMPTY_STRING_ARRAY;
   12424                 } else {
   12425                     name = args[opti];
   12426                     opti++;
   12427                     newArgs = new String[args.length - opti];
   12428                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12429                             args.length - opti);
   12430                 }
   12431                 synchronized (this) {
   12432                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   12433                 }
   12434             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   12435                 String[] newArgs;
   12436                 String name;
   12437                 if (opti >= args.length) {
   12438                     name = null;
   12439                     newArgs = EMPTY_STRING_ARRAY;
   12440                 } else {
   12441                     name = args[opti];
   12442                     opti++;
   12443                     newArgs = new String[args.length - opti];
   12444                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12445                             args.length - opti);
   12446                 }
   12447                 synchronized (this) {
   12448                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   12449                 }
   12450             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   12451                 synchronized (this) {
   12452                     dumpOomLocked(fd, pw, args, opti, true);
   12453                 }
   12454             } else if ("provider".equals(cmd)) {
   12455                 String[] newArgs;
   12456                 String name;
   12457                 if (opti >= args.length) {
   12458                     name = null;
   12459                     newArgs = EMPTY_STRING_ARRAY;
   12460                 } else {
   12461                     name = args[opti];
   12462                     opti++;
   12463                     newArgs = new String[args.length - opti];
   12464                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   12465                 }
   12466                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   12467                     pw.println("No providers match: " + name);
   12468                     pw.println("Use -h for help.");
   12469                 }
   12470             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   12471                 synchronized (this) {
   12472                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   12473                 }
   12474             } else if ("service".equals(cmd)) {
   12475                 String[] newArgs;
   12476                 String name;
   12477                 if (opti >= args.length) {
   12478                     name = null;
   12479                     newArgs = EMPTY_STRING_ARRAY;
   12480                 } else {
   12481                     name = args[opti];
   12482                     opti++;
   12483                     newArgs = new String[args.length - opti];
   12484                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12485                             args.length - opti);
   12486                 }
   12487                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   12488                     pw.println("No services match: " + name);
   12489                     pw.println("Use -h for help.");
   12490                 }
   12491             } else if ("package".equals(cmd)) {
   12492                 String[] newArgs;
   12493                 if (opti >= args.length) {
   12494                     pw.println("package: no package name specified");
   12495                     pw.println("Use -h for help.");
   12496                 } else {
   12497                     dumpPackage = args[opti];
   12498                     opti++;
   12499                     newArgs = new String[args.length - opti];
   12500                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   12501                             args.length - opti);
   12502                     args = newArgs;
   12503                     opti = 0;
   12504                     more = true;
   12505                 }
   12506             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   12507                 synchronized (this) {
   12508                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   12509                 }
   12510             } else if ("write".equals(cmd)) {
   12511                 mTaskPersister.flush();
   12512                 pw.println("All tasks persisted.");
   12513                 return;
   12514             } else {
   12515                 // Dumping a single activity?
   12516                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   12517                     pw.println("Bad activity command, or no activities match: " + cmd);
   12518                     pw.println("Use -h for help.");
   12519                 }
   12520             }
   12521             if (!more) {
   12522                 Binder.restoreCallingIdentity(origId);
   12523                 return;
   12524             }
   12525         }
   12526 
   12527         // No piece of data specified, dump everything.
   12528         synchronized (this) {
   12529             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12530             pw.println();
   12531             if (dumpAll) {
   12532                 pw.println("-------------------------------------------------------------------------------");
   12533             }
   12534             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12535             pw.println();
   12536             if (dumpAll) {
   12537                 pw.println("-------------------------------------------------------------------------------");
   12538             }
   12539             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12540             pw.println();
   12541             if (dumpAll) {
   12542                 pw.println("-------------------------------------------------------------------------------");
   12543             }
   12544             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12545             pw.println();
   12546             if (dumpAll) {
   12547                 pw.println("-------------------------------------------------------------------------------");
   12548             }
   12549             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12550             pw.println();
   12551             if (dumpAll) {
   12552                 pw.println("-------------------------------------------------------------------------------");
   12553             }
   12554             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   12555             pw.println();
   12556             if (dumpAll) {
   12557                 pw.println("-------------------------------------------------------------------------------");
   12558             }
   12559             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   12560         }
   12561         Binder.restoreCallingIdentity(origId);
   12562     }
   12563 
   12564     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12565             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   12566         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   12567 
   12568         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   12569                 dumpPackage);
   12570         boolean needSep = printedAnything;
   12571 
   12572         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   12573                 dumpPackage, needSep, "  mFocusedActivity: ");
   12574         if (printed) {
   12575             printedAnything = true;
   12576             needSep = false;
   12577         }
   12578 
   12579         if (dumpPackage == null) {
   12580             if (needSep) {
   12581                 pw.println();
   12582             }
   12583             needSep = true;
   12584             printedAnything = true;
   12585             mStackSupervisor.dump(pw, "  ");
   12586         }
   12587 
   12588         if (!printedAnything) {
   12589             pw.println("  (nothing)");
   12590         }
   12591     }
   12592 
   12593     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12594             int opti, boolean dumpAll, String dumpPackage) {
   12595         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
   12596 
   12597         boolean printedAnything = false;
   12598 
   12599         if (mRecentTasks != null && mRecentTasks.size() > 0) {
   12600             boolean printedHeader = false;
   12601 
   12602             final int N = mRecentTasks.size();
   12603             for (int i=0; i<N; i++) {
   12604                 TaskRecord tr = mRecentTasks.get(i);
   12605                 if (dumpPackage != null) {
   12606                     if (tr.realActivity == null ||
   12607                             !dumpPackage.equals(tr.realActivity)) {
   12608                         continue;
   12609                     }
   12610                 }
   12611                 if (!printedHeader) {
   12612                     pw.println("  Recent tasks:");
   12613                     printedHeader = true;
   12614                     printedAnything = true;
   12615                 }
   12616                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   12617                         pw.println(tr);
   12618                 if (dumpAll) {
   12619                     mRecentTasks.get(i).dump(pw, "    ");
   12620                 }
   12621             }
   12622         }
   12623 
   12624         if (!printedAnything) {
   12625             pw.println("  (nothing)");
   12626         }
   12627     }
   12628 
   12629     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   12630             int opti, boolean dumpAll, String dumpPackage) {
   12631         boolean needSep = false;
   12632         boolean printedAnything = false;
   12633         int numPers = 0;
   12634 
   12635         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   12636 
   12637         if (dumpAll) {
   12638             final int NP = mProcessNames.getMap().size();
   12639             for (int ip=0; ip<NP; ip++) {
   12640                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   12641                 final int NA = procs.size();
   12642                 for (int ia=0; ia<NA; ia++) {
   12643                     ProcessRecord r = procs.valueAt(ia);
   12644                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12645                         continue;
   12646                     }
   12647                     if (!needSep) {
   12648                         pw.println("  All known processes:");
   12649                         needSep = true;
   12650                         printedAnything = true;
   12651                     }
   12652                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   12653                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   12654                         pw.print(" "); pw.println(r);
   12655                     r.dump(pw, "    ");
   12656                     if (r.persistent) {
   12657                         numPers++;
   12658                     }
   12659                 }
   12660             }
   12661         }
   12662 
   12663         if (mIsolatedProcesses.size() > 0) {
   12664             boolean printed = false;
   12665             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   12666                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   12667                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12668                     continue;
   12669                 }
   12670                 if (!printed) {
   12671                     if (needSep) {
   12672                         pw.println();
   12673                     }
   12674                     pw.println("  Isolated process list (sorted by uid):");
   12675                     printedAnything = true;
   12676                     printed = true;
   12677                     needSep = true;
   12678                 }
   12679                 pw.println(String.format("%sIsolated #%2d: %s",
   12680                         "    ", i, r.toString()));
   12681             }
   12682         }
   12683 
   12684         if (mLruProcesses.size() > 0) {
   12685             if (needSep) {
   12686                 pw.println();
   12687             }
   12688             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   12689                     pw.print(" total, non-act at ");
   12690                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   12691                     pw.print(", non-svc at ");
   12692                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   12693                     pw.println("):");
   12694             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   12695             needSep = true;
   12696             printedAnything = true;
   12697         }
   12698 
   12699         if (dumpAll || dumpPackage != null) {
   12700             synchronized (mPidsSelfLocked) {
   12701                 boolean printed = false;
   12702                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   12703                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   12704                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   12705                         continue;
   12706                     }
   12707                     if (!printed) {
   12708                         if (needSep) pw.println();
   12709                         needSep = true;
   12710                         pw.println("  PID mappings:");
   12711                         printed = true;
   12712                         printedAnything = true;
   12713                     }
   12714                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   12715                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   12716                 }
   12717             }
   12718         }
   12719 
   12720         if (mForegroundProcesses.size() > 0) {
   12721             synchronized (mPidsSelfLocked) {
   12722                 boolean printed = false;
   12723                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   12724                     ProcessRecord r = mPidsSelfLocked.get(
   12725                             mForegroundProcesses.valueAt(i).pid);
   12726                     if (dumpPackage != null && (r == null
   12727                             || !r.pkgList.containsKey(dumpPackage))) {
   12728                         continue;
   12729                     }
   12730                     if (!printed) {
   12731                         if (needSep) pw.println();
   12732                         needSep = true;
   12733                         pw.println("  Foreground Processes:");
   12734                         printed = true;
   12735                         printedAnything = true;
   12736                     }
   12737                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   12738                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   12739                 }
   12740             }
   12741         }
   12742 
   12743         if (mPersistentStartingProcesses.size() > 0) {
   12744             if (needSep) pw.println();
   12745             needSep = true;
   12746             printedAnything = true;
   12747             pw.println("  Persisent processes that are starting:");
   12748             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   12749                     "Starting Norm", "Restarting PERS", dumpPackage);
   12750         }
   12751 
   12752         if (mRemovedProcesses.size() > 0) {
   12753             if (needSep) pw.println();
   12754             needSep = true;
   12755             printedAnything = true;
   12756             pw.println("  Processes that are being removed:");
   12757             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   12758                     "Removed Norm", "Removed PERS", dumpPackage);
   12759         }
   12760 
   12761         if (mProcessesOnHold.size() > 0) {
   12762             if (needSep) pw.println();
   12763             needSep = true;
   12764             printedAnything = true;
   12765             pw.println("  Processes that are on old until the system is ready:");
   12766             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   12767                     "OnHold Norm", "OnHold PERS", dumpPackage);
   12768         }
   12769 
   12770         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   12771 
   12772         if (mProcessCrashTimes.getMap().size() > 0) {
   12773             boolean printed = false;
   12774             long now = SystemClock.uptimeMillis();
   12775             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   12776             final int NP = pmap.size();
   12777             for (int ip=0; ip<NP; ip++) {
   12778                 String pname = pmap.keyAt(ip);
   12779                 SparseArray<Long> uids = pmap.valueAt(ip);
   12780                 final int N = uids.size();
   12781                 for (int i=0; i<N; i++) {
   12782                     int puid = uids.keyAt(i);
   12783                     ProcessRecord r = mProcessNames.get(pname, puid);
   12784                     if (dumpPackage != null && (r == null
   12785                             || !r.pkgList.containsKey(dumpPackage))) {
   12786                         continue;
   12787                     }
   12788                     if (!printed) {
   12789                         if (needSep) pw.println();
   12790                         needSep = true;
   12791                         pw.println("  Time since processes crashed:");
   12792                         printed = true;
   12793                         printedAnything = true;
   12794                     }
   12795                     pw.print("    Process "); pw.print(pname);
   12796                             pw.print(" uid "); pw.print(puid);
   12797                             pw.print(": last crashed ");
   12798                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   12799                             pw.println(" ago");
   12800                 }
   12801             }
   12802         }
   12803 
   12804         if (mBadProcesses.getMap().size() > 0) {
   12805             boolean printed = false;
   12806             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
   12807             final int NP = pmap.size();
   12808             for (int ip=0; ip<NP; ip++) {
   12809                 String pname = pmap.keyAt(ip);
   12810                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
   12811                 final int N = uids.size();
   12812                 for (int i=0; i<N; i++) {
   12813                     int puid = uids.keyAt(i);
   12814                     ProcessRecord r = mProcessNames.get(pname, puid);
   12815                     if (dumpPackage != null && (r == null
   12816                             || !r.pkgList.containsKey(dumpPackage))) {
   12817                         continue;
   12818                     }
   12819                     if (!printed) {
   12820                         if (needSep) pw.println();
   12821                         needSep = true;
   12822                         pw.println("  Bad processes:");
   12823                         printedAnything = true;
   12824                     }
   12825                     BadProcessInfo info = uids.valueAt(i);
   12826                     pw.print("    Bad process "); pw.print(pname);
   12827                             pw.print(" uid "); pw.print(puid);
   12828                             pw.print(": crashed at time "); pw.println(info.time);
   12829                     if (info.shortMsg != null) {
   12830                         pw.print("      Short msg: "); pw.println(info.shortMsg);
   12831                     }
   12832                     if (info.longMsg != null) {
   12833                         pw.print("      Long msg: "); pw.println(info.longMsg);
   12834                     }
   12835                     if (info.stack != null) {
   12836                         pw.println("      Stack:");
   12837                         int lastPos = 0;
   12838                         for (int pos=0; pos<info.stack.length(); pos++) {
   12839                             if (info.stack.charAt(pos) == '\n') {
   12840                                 pw.print("        ");
   12841                                 pw.write(info.stack, lastPos, pos-lastPos);
   12842                                 pw.println();
   12843                                 lastPos = pos+1;
   12844                             }
   12845                         }
   12846                         if (lastPos < info.stack.length()) {
   12847                             pw.print("        ");
   12848                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
   12849                             pw.println();
   12850                         }
   12851                     }
   12852                 }
   12853             }
   12854         }
   12855 
   12856         if (dumpPackage == null) {
   12857             pw.println();
   12858             needSep = false;
   12859             pw.println("  mStartedUsers:");
   12860             for (int i=0; i<mStartedUsers.size(); i++) {
   12861                 UserStartedState uss = mStartedUsers.valueAt(i);
   12862                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   12863                         pw.print(": "); uss.dump("", pw);
   12864             }
   12865             pw.print("  mStartedUserArray: [");
   12866             for (int i=0; i<mStartedUserArray.length; i++) {
   12867                 if (i > 0) pw.print(", ");
   12868                 pw.print(mStartedUserArray[i]);
   12869             }
   12870             pw.println("]");
   12871             pw.print("  mUserLru: [");
   12872             for (int i=0; i<mUserLru.size(); i++) {
   12873                 if (i > 0) pw.print(", ");
   12874                 pw.print(mUserLru.get(i));
   12875             }
   12876             pw.println("]");
   12877             if (dumpAll) {
   12878                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   12879             }
   12880             synchronized (mUserProfileGroupIdsSelfLocked) {
   12881                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
   12882                     pw.println("  mUserProfileGroupIds:");
   12883                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
   12884                         pw.print("    User #");
   12885                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
   12886                         pw.print(" -> profile #");
   12887                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
   12888                     }
   12889                 }
   12890             }
   12891         }
   12892         if (mHomeProcess != null && (dumpPackage == null
   12893                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   12894             if (needSep) {
   12895                 pw.println();
   12896                 needSep = false;
   12897             }
   12898             pw.println("  mHomeProcess: " + mHomeProcess);
   12899         }
   12900         if (mPreviousProcess != null && (dumpPackage == null
   12901                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   12902             if (needSep) {
   12903                 pw.println();
   12904                 needSep = false;
   12905             }
   12906             pw.println("  mPreviousProcess: " + mPreviousProcess);
   12907         }
   12908         if (dumpAll) {
   12909             StringBuilder sb = new StringBuilder(128);
   12910             sb.append("  mPreviousProcessVisibleTime: ");
   12911             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   12912             pw.println(sb);
   12913         }
   12914         if (mHeavyWeightProcess != null && (dumpPackage == null
   12915                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   12916             if (needSep) {
   12917                 pw.println();
   12918                 needSep = false;
   12919             }
   12920             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   12921         }
   12922         if (dumpPackage == null) {
   12923             pw.println("  mConfiguration: " + mConfiguration);
   12924         }
   12925         if (dumpAll) {
   12926             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   12927             if (mCompatModePackages.getPackages().size() > 0) {
   12928                 boolean printed = false;
   12929                 for (Map.Entry<String, Integer> entry
   12930                         : mCompatModePackages.getPackages().entrySet()) {
   12931                     String pkg = entry.getKey();
   12932                     int mode = entry.getValue();
   12933                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   12934                         continue;
   12935                     }
   12936                     if (!printed) {
   12937                         pw.println("  mScreenCompatPackages:");
   12938                         printed = true;
   12939                     }
   12940                     pw.print("    "); pw.print(pkg); pw.print(": ");
   12941                             pw.print(mode); pw.println();
   12942                 }
   12943             }
   12944         }
   12945         if (dumpPackage == null) {
   12946             if (mSleeping || mWentToSleep || mLockScreenShown) {
   12947                 pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   12948                         + " mLockScreenShown " + mLockScreenShown);
   12949             }
   12950             if (mShuttingDown || mRunningVoice) {
   12951                 pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
   12952             }
   12953         }
   12954         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   12955                 || mOrigWaitForDebugger) {
   12956             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   12957                     || dumpPackage.equals(mOrigDebugApp)) {
   12958                 if (needSep) {
   12959                     pw.println();
   12960                     needSep = false;
   12961                 }
   12962                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   12963                         + " mDebugTransient=" + mDebugTransient
   12964                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   12965             }
   12966         }
   12967         if (mOpenGlTraceApp != null) {
   12968             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   12969                 if (needSep) {
   12970                     pw.println();
   12971                     needSep = false;
   12972                 }
   12973                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   12974             }
   12975         }
   12976         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   12977                 || mProfileFd != null) {
   12978             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   12979                 if (needSep) {
   12980                     pw.println();
   12981                     needSep = false;
   12982                 }
   12983                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   12984                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   12985                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
   12986                         + mAutoStopProfiler);
   12987                 pw.println("  mProfileType=" + mProfileType);
   12988             }
   12989         }
   12990         if (dumpPackage == null) {
   12991             if (mAlwaysFinishActivities || mController != null) {
   12992                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   12993                         + " mController=" + mController);
   12994             }
   12995             if (dumpAll) {
   12996                 pw.println("  Total persistent processes: " + numPers);
   12997                 pw.println("  mProcessesReady=" + mProcessesReady
   12998                         + " mSystemReady=" + mSystemReady
   12999                         + " mBooted=" + mBooted
   13000                         + " mFactoryTest=" + mFactoryTest);
   13001                 pw.println("  mBooting=" + mBooting
   13002                         + " mCallFinishBooting=" + mCallFinishBooting
   13003                         + " mBootAnimationComplete=" + mBootAnimationComplete);
   13004                 pw.print("  mLastPowerCheckRealtime=");
   13005                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   13006                         pw.println("");
   13007                 pw.print("  mLastPowerCheckUptime=");
   13008                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   13009                         pw.println("");
   13010                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   13011                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   13012                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   13013                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   13014                         + " (" + mLruProcesses.size() + " total)"
   13015                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   13016                         + " mNumServiceProcs=" + mNumServiceProcs
   13017                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   13018                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   13019                         + " mLastMemoryLevel" + mLastMemoryLevel
   13020                         + " mLastNumProcesses" + mLastNumProcesses);
   13021                 long now = SystemClock.uptimeMillis();
   13022                 pw.print("  mLastIdleTime=");
   13023                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   13024                         pw.print(" mLowRamSinceLastIdle=");
   13025                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   13026                         pw.println();
   13027             }
   13028         }
   13029 
   13030         if (!printedAnything) {
   13031             pw.println("  (nothing)");
   13032         }
   13033     }
   13034 
   13035     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   13036             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   13037         if (mProcessesToGc.size() > 0) {
   13038             boolean printed = false;
   13039             long now = SystemClock.uptimeMillis();
   13040             for (int i=0; i<mProcessesToGc.size(); i++) {
   13041                 ProcessRecord proc = mProcessesToGc.get(i);
   13042                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   13043                     continue;
   13044                 }
   13045                 if (!printed) {
   13046                     if (needSep) pw.println();
   13047                     needSep = true;
   13048                     pw.println("  Processes that are waiting to GC:");
   13049                     printed = true;
   13050                 }
   13051                 pw.print("    Process "); pw.println(proc);
   13052                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   13053                         pw.print(", last gced=");
   13054                         pw.print(now-proc.lastRequestedGc);
   13055                         pw.print(" ms ago, last lowMem=");
   13056                         pw.print(now-proc.lastLowMemory);
   13057                         pw.println(" ms ago");
   13058 
   13059             }
   13060         }
   13061         return needSep;
   13062     }
   13063 
   13064     void printOomLevel(PrintWriter pw, String name, int adj) {
   13065         pw.print("    ");
   13066         if (adj >= 0) {
   13067             pw.print(' ');
   13068             if (adj < 10) pw.print(' ');
   13069         } else {
   13070             if (adj > -10) pw.print(' ');
   13071         }
   13072         pw.print(adj);
   13073         pw.print(": ");
   13074         pw.print(name);
   13075         pw.print(" (");
   13076         pw.print(mProcessList.getMemLevel(adj)/1024);
   13077         pw.println(" kB)");
   13078     }
   13079 
   13080     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13081             int opti, boolean dumpAll) {
   13082         boolean needSep = false;
   13083 
   13084         if (mLruProcesses.size() > 0) {
   13085             if (needSep) pw.println();
   13086             needSep = true;
   13087             pw.println("  OOM levels:");
   13088             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   13089             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   13090             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
   13091             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   13092             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   13093             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   13094             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   13095             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   13096             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   13097             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   13098             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   13099             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   13100             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   13101             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   13102 
   13103             if (needSep) pw.println();
   13104             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   13105                     pw.print(" total, non-act at ");
   13106                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   13107                     pw.print(", non-svc at ");
   13108                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   13109                     pw.println("):");
   13110             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   13111             needSep = true;
   13112         }
   13113 
   13114         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   13115 
   13116         pw.println();
   13117         pw.println("  mHomeProcess: " + mHomeProcess);
   13118         pw.println("  mPreviousProcess: " + mPreviousProcess);
   13119         if (mHeavyWeightProcess != null) {
   13120             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   13121         }
   13122 
   13123         return true;
   13124     }
   13125 
   13126     /**
   13127      * There are three ways to call this:
   13128      *  - no provider specified: dump all the providers
   13129      *  - a flattened component name that matched an existing provider was specified as the
   13130      *    first arg: dump that one provider
   13131      *  - the first arg isn't the flattened component name of an existing provider:
   13132      *    dump all providers whose component contains the first arg as a substring
   13133      */
   13134     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13135             int opti, boolean dumpAll) {
   13136         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   13137     }
   13138 
   13139     static class ItemMatcher {
   13140         ArrayList<ComponentName> components;
   13141         ArrayList<String> strings;
   13142         ArrayList<Integer> objects;
   13143         boolean all;
   13144 
   13145         ItemMatcher() {
   13146             all = true;
   13147         }
   13148 
   13149         void build(String name) {
   13150             ComponentName componentName = ComponentName.unflattenFromString(name);
   13151             if (componentName != null) {
   13152                 if (components == null) {
   13153                     components = new ArrayList<ComponentName>();
   13154                 }
   13155                 components.add(componentName);
   13156                 all = false;
   13157             } else {
   13158                 int objectId = 0;
   13159                 // Not a '/' separated full component name; maybe an object ID?
   13160                 try {
   13161                     objectId = Integer.parseInt(name, 16);
   13162                     if (objects == null) {
   13163                         objects = new ArrayList<Integer>();
   13164                     }
   13165                     objects.add(objectId);
   13166                     all = false;
   13167                 } catch (RuntimeException e) {
   13168                     // Not an integer; just do string match.
   13169                     if (strings == null) {
   13170                         strings = new ArrayList<String>();
   13171                     }
   13172                     strings.add(name);
   13173                     all = false;
   13174                 }
   13175             }
   13176         }
   13177 
   13178         int build(String[] args, int opti) {
   13179             for (; opti<args.length; opti++) {
   13180                 String name = args[opti];
   13181                 if ("--".equals(name)) {
   13182                     return opti+1;
   13183                 }
   13184                 build(name);
   13185             }
   13186             return opti;
   13187         }
   13188 
   13189         boolean match(Object object, ComponentName comp) {
   13190             if (all) {
   13191                 return true;
   13192             }
   13193             if (components != null) {
   13194                 for (int i=0; i<components.size(); i++) {
   13195                     if (components.get(i).equals(comp)) {
   13196                         return true;
   13197                     }
   13198                 }
   13199             }
   13200             if (objects != null) {
   13201                 for (int i=0; i<objects.size(); i++) {
   13202                     if (System.identityHashCode(object) == objects.get(i)) {
   13203                         return true;
   13204                     }
   13205                 }
   13206             }
   13207             if (strings != null) {
   13208                 String flat = comp.flattenToString();
   13209                 for (int i=0; i<strings.size(); i++) {
   13210                     if (flat.contains(strings.get(i))) {
   13211                         return true;
   13212                     }
   13213                 }
   13214             }
   13215             return false;
   13216         }
   13217     }
   13218 
   13219     /**
   13220      * There are three things that cmd can be:
   13221      *  - a flattened component name that matches an existing activity
   13222      *  - the cmd arg isn't the flattened component name of an existing activity:
   13223      *    dump all activity whose component contains the cmd as a substring
   13224      *  - A hex number of the ActivityRecord object instance.
   13225      */
   13226     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   13227             int opti, boolean dumpAll) {
   13228         ArrayList<ActivityRecord> activities;
   13229 
   13230         synchronized (this) {
   13231             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   13232         }
   13233 
   13234         if (activities.size() <= 0) {
   13235             return false;
   13236         }
   13237 
   13238         String[] newArgs = new String[args.length - opti];
   13239         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   13240 
   13241         TaskRecord lastTask = null;
   13242         boolean needSep = false;
   13243         for (int i=activities.size()-1; i>=0; i--) {
   13244             ActivityRecord r = activities.get(i);
   13245             if (needSep) {
   13246                 pw.println();
   13247             }
   13248             needSep = true;
   13249             synchronized (this) {
   13250                 if (lastTask != r.task) {
   13251                     lastTask = r.task;
   13252                     pw.print("TASK "); pw.print(lastTask.affinity);
   13253                             pw.print(" id="); pw.println(lastTask.taskId);
   13254                     if (dumpAll) {
   13255                         lastTask.dump(pw, "  ");
   13256                     }
   13257                 }
   13258             }
   13259             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   13260         }
   13261         return true;
   13262     }
   13263 
   13264     /**
   13265      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   13266      * there is a thread associated with the activity.
   13267      */
   13268     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   13269             final ActivityRecord r, String[] args, boolean dumpAll) {
   13270         String innerPrefix = prefix + "  ";
   13271         synchronized (this) {
   13272             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   13273                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   13274                     pw.print(" pid=");
   13275                     if (r.app != null) pw.println(r.app.pid);
   13276                     else pw.println("(not running)");
   13277             if (dumpAll) {
   13278                 r.dump(pw, innerPrefix);
   13279             }
   13280         }
   13281         if (r.app != null && r.app.thread != null) {
   13282             // flush anything that is already in the PrintWriter since the thread is going
   13283             // to write to the file descriptor directly
   13284             pw.flush();
   13285             try {
   13286                 TransferPipe tp = new TransferPipe();
   13287                 try {
   13288                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   13289                             r.appToken, innerPrefix, args);
   13290                     tp.go(fd);
   13291                 } finally {
   13292                     tp.kill();
   13293                 }
   13294             } catch (IOException e) {
   13295                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   13296             } catch (RemoteException e) {
   13297                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   13298             }
   13299         }
   13300     }
   13301 
   13302     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13303             int opti, boolean dumpAll, String dumpPackage) {
   13304         boolean needSep = false;
   13305         boolean onlyHistory = false;
   13306         boolean printedAnything = false;
   13307 
   13308         if ("history".equals(dumpPackage)) {
   13309             if (opti < args.length && "-s".equals(args[opti])) {
   13310                 dumpAll = false;
   13311             }
   13312             onlyHistory = true;
   13313             dumpPackage = null;
   13314         }
   13315 
   13316         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   13317         if (!onlyHistory && dumpAll) {
   13318             if (mRegisteredReceivers.size() > 0) {
   13319                 boolean printed = false;
   13320                 Iterator it = mRegisteredReceivers.values().iterator();
   13321                 while (it.hasNext()) {
   13322                     ReceiverList r = (ReceiverList)it.next();
   13323                     if (dumpPackage != null && (r.app == null ||
   13324                             !dumpPackage.equals(r.app.info.packageName))) {
   13325                         continue;
   13326                     }
   13327                     if (!printed) {
   13328                         pw.println("  Registered Receivers:");
   13329                         needSep = true;
   13330                         printed = true;
   13331                         printedAnything = true;
   13332                     }
   13333                     pw.print("  * "); pw.println(r);
   13334                     r.dump(pw, "    ");
   13335                 }
   13336             }
   13337 
   13338             if (mReceiverResolver.dump(pw, needSep ?
   13339                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   13340                     "    ", dumpPackage, false)) {
   13341                 needSep = true;
   13342                 printedAnything = true;
   13343             }
   13344         }
   13345 
   13346         for (BroadcastQueue q : mBroadcastQueues) {
   13347             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   13348             printedAnything |= needSep;
   13349         }
   13350 
   13351         needSep = true;
   13352 
   13353         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   13354             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   13355                 if (needSep) {
   13356                     pw.println();
   13357                 }
   13358                 needSep = true;
   13359                 printedAnything = true;
   13360                 pw.print("  Sticky broadcasts for user ");
   13361                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   13362                 StringBuilder sb = new StringBuilder(128);
   13363                 for (Map.Entry<String, ArrayList<Intent>> ent
   13364                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   13365                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   13366                     if (dumpAll) {
   13367                         pw.println(":");
   13368                         ArrayList<Intent> intents = ent.getValue();
   13369                         final int N = intents.size();
   13370                         for (int i=0; i<N; i++) {
   13371                             sb.setLength(0);
   13372                             sb.append("    Intent: ");
   13373                             intents.get(i).toShortString(sb, false, true, false, false);
   13374                             pw.println(sb.toString());
   13375                             Bundle bundle = intents.get(i).getExtras();
   13376                             if (bundle != null) {
   13377                                 pw.print("      ");
   13378                                 pw.println(bundle.toString());
   13379                             }
   13380                         }
   13381                     } else {
   13382                         pw.println("");
   13383                     }
   13384                 }
   13385             }
   13386         }
   13387 
   13388         if (!onlyHistory && dumpAll) {
   13389             pw.println();
   13390             for (BroadcastQueue queue : mBroadcastQueues) {
   13391                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   13392                         + queue.mBroadcastsScheduled);
   13393             }
   13394             pw.println("  mHandler:");
   13395             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   13396             needSep = true;
   13397             printedAnything = true;
   13398         }
   13399 
   13400         if (!printedAnything) {
   13401             pw.println("  (nothing)");
   13402         }
   13403     }
   13404 
   13405     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13406             int opti, boolean dumpAll, String dumpPackage) {
   13407         boolean needSep;
   13408         boolean printedAnything = false;
   13409 
   13410         ItemMatcher matcher = new ItemMatcher();
   13411         matcher.build(args, opti);
   13412 
   13413         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   13414 
   13415         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   13416         printedAnything |= needSep;
   13417 
   13418         if (mLaunchingProviders.size() > 0) {
   13419             boolean printed = false;
   13420             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   13421                 ContentProviderRecord r = mLaunchingProviders.get(i);
   13422                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   13423                     continue;
   13424                 }
   13425                 if (!printed) {
   13426                     if (needSep) pw.println();
   13427                     needSep = true;
   13428                     pw.println("  Launching content providers:");
   13429                     printed = true;
   13430                     printedAnything = true;
   13431                 }
   13432                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   13433                         pw.println(r);
   13434             }
   13435         }
   13436 
   13437         if (mGrantedUriPermissions.size() > 0) {
   13438             boolean printed = false;
   13439             int dumpUid = -2;
   13440             if (dumpPackage != null) {
   13441                 try {
   13442                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   13443                 } catch (NameNotFoundException e) {
   13444                     dumpUid = -1;
   13445                 }
   13446             }
   13447             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   13448                 int uid = mGrantedUriPermissions.keyAt(i);
   13449                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   13450                     continue;
   13451                 }
   13452                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   13453                 if (!printed) {
   13454                     if (needSep) pw.println();
   13455                     needSep = true;
   13456                     pw.println("  Granted Uri Permissions:");
   13457                     printed = true;
   13458                     printedAnything = true;
   13459                 }
   13460                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
   13461                 for (UriPermission perm : perms.values()) {
   13462                     pw.print("    "); pw.println(perm);
   13463                     if (dumpAll) {
   13464                         perm.dump(pw, "      ");
   13465                     }
   13466                 }
   13467             }
   13468         }
   13469 
   13470         if (!printedAnything) {
   13471             pw.println("  (nothing)");
   13472         }
   13473     }
   13474 
   13475     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   13476             int opti, boolean dumpAll, String dumpPackage) {
   13477         boolean printed = false;
   13478 
   13479         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   13480 
   13481         if (mIntentSenderRecords.size() > 0) {
   13482             Iterator<WeakReference<PendingIntentRecord>> it
   13483                     = mIntentSenderRecords.values().iterator();
   13484             while (it.hasNext()) {
   13485                 WeakReference<PendingIntentRecord> ref = it.next();
   13486                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   13487                 if (dumpPackage != null && (rec == null
   13488                         || !dumpPackage.equals(rec.key.packageName))) {
   13489                     continue;
   13490                 }
   13491                 printed = true;
   13492                 if (rec != null) {
   13493                     pw.print("  * "); pw.println(rec);
   13494                     if (dumpAll) {
   13495                         rec.dump(pw, "    ");
   13496                     }
   13497                 } else {
   13498                     pw.print("  * "); pw.println(ref);
   13499                 }
   13500             }
   13501         }
   13502 
   13503         if (!printed) {
   13504             pw.println("  (nothing)");
   13505         }
   13506     }
   13507 
   13508     private static final int dumpProcessList(PrintWriter pw,
   13509             ActivityManagerService service, List list,
   13510             String prefix, String normalLabel, String persistentLabel,
   13511             String dumpPackage) {
   13512         int numPers = 0;
   13513         final int N = list.size()-1;
   13514         for (int i=N; i>=0; i--) {
   13515             ProcessRecord r = (ProcessRecord)list.get(i);
   13516             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   13517                 continue;
   13518             }
   13519             pw.println(String.format("%s%s #%2d: %s",
   13520                     prefix, (r.persistent ? persistentLabel : normalLabel),
   13521                     i, r.toString()));
   13522             if (r.persistent) {
   13523                 numPers++;
   13524             }
   13525         }
   13526         return numPers;
   13527     }
   13528 
   13529     private static final boolean dumpProcessOomList(PrintWriter pw,
   13530             ActivityManagerService service, List<ProcessRecord> origList,
   13531             String prefix, String normalLabel, String persistentLabel,
   13532             boolean inclDetails, String dumpPackage) {
   13533 
   13534         ArrayList<Pair<ProcessRecord, Integer>> list
   13535                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   13536         for (int i=0; i<origList.size(); i++) {
   13537             ProcessRecord r = origList.get(i);
   13538             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   13539                 continue;
   13540             }
   13541             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   13542         }
   13543 
   13544         if (list.size() <= 0) {
   13545             return false;
   13546         }
   13547 
   13548         Comparator<Pair<ProcessRecord, Integer>> comparator
   13549                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   13550             @Override
   13551             public int compare(Pair<ProcessRecord, Integer> object1,
   13552                     Pair<ProcessRecord, Integer> object2) {
   13553                 if (object1.first.setAdj != object2.first.setAdj) {
   13554                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   13555                 }
   13556                 if (object1.second.intValue() != object2.second.intValue()) {
   13557                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   13558                 }
   13559                 return 0;
   13560             }
   13561         };
   13562 
   13563         Collections.sort(list, comparator);
   13564 
   13565         final long curRealtime = SystemClock.elapsedRealtime();
   13566         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   13567         final long curUptime = SystemClock.uptimeMillis();
   13568         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   13569 
   13570         for (int i=list.size()-1; i>=0; i--) {
   13571             ProcessRecord r = list.get(i).first;
   13572             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   13573             char schedGroup;
   13574             switch (r.setSchedGroup) {
   13575                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   13576                     schedGroup = 'B';
   13577                     break;
   13578                 case Process.THREAD_GROUP_DEFAULT:
   13579                     schedGroup = 'F';
   13580                     break;
   13581                 default:
   13582                     schedGroup = '?';
   13583                     break;
   13584             }
   13585             char foreground;
   13586             if (r.foregroundActivities) {
   13587                 foreground = 'A';
   13588             } else if (r.foregroundServices) {
   13589                 foreground = 'S';
   13590             } else {
   13591                 foreground = ' ';
   13592             }
   13593             String procState = ProcessList.makeProcStateString(r.curProcState);
   13594             pw.print(prefix);
   13595             pw.print(r.persistent ? persistentLabel : normalLabel);
   13596             pw.print(" #");
   13597             int num = (origList.size()-1)-list.get(i).second;
   13598             if (num < 10) pw.print(' ');
   13599             pw.print(num);
   13600             pw.print(": ");
   13601             pw.print(oomAdj);
   13602             pw.print(' ');
   13603             pw.print(schedGroup);
   13604             pw.print('/');
   13605             pw.print(foreground);
   13606             pw.print('/');
   13607             pw.print(procState);
   13608             pw.print(" trm:");
   13609             if (r.trimMemoryLevel < 10) pw.print(' ');
   13610             pw.print(r.trimMemoryLevel);
   13611             pw.print(' ');
   13612             pw.print(r.toShortString());
   13613             pw.print(" (");
   13614             pw.print(r.adjType);
   13615             pw.println(')');
   13616             if (r.adjSource != null || r.adjTarget != null) {
   13617                 pw.print(prefix);
   13618                 pw.print("    ");
   13619                 if (r.adjTarget instanceof ComponentName) {
   13620                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   13621                 } else if (r.adjTarget != null) {
   13622                     pw.print(r.adjTarget.toString());
   13623                 } else {
   13624                     pw.print("{null}");
   13625                 }
   13626                 pw.print("<=");
   13627                 if (r.adjSource instanceof ProcessRecord) {
   13628                     pw.print("Proc{");
   13629                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   13630                     pw.println("}");
   13631                 } else if (r.adjSource != null) {
   13632                     pw.println(r.adjSource.toString());
   13633                 } else {
   13634                     pw.println("{null}");
   13635                 }
   13636             }
   13637             if (inclDetails) {
   13638                 pw.print(prefix);
   13639                 pw.print("    ");
   13640                 pw.print("oom: max="); pw.print(r.maxAdj);
   13641                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   13642                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   13643                 pw.print(" cur="); pw.print(r.curAdj);
   13644                 pw.print(" set="); pw.println(r.setAdj);
   13645                 pw.print(prefix);
   13646                 pw.print("    ");
   13647                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   13648                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   13649                 pw.print(" lastPss="); pw.print(r.lastPss);
   13650                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   13651                 pw.print(prefix);
   13652                 pw.print("    ");
   13653                 pw.print("cached="); pw.print(r.cached);
   13654                 pw.print(" empty="); pw.print(r.empty);
   13655                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   13656 
   13657                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
   13658                     if (r.lastWakeTime != 0) {
   13659                         long wtime;
   13660                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   13661                         synchronized (stats) {
   13662                             wtime = stats.getProcessWakeTime(r.info.uid,
   13663                                     r.pid, curRealtime);
   13664                         }
   13665                         long timeUsed = wtime - r.lastWakeTime;
   13666                         pw.print(prefix);
   13667                         pw.print("    ");
   13668                         pw.print("keep awake over ");
   13669                         TimeUtils.formatDuration(realtimeSince, pw);
   13670                         pw.print(" used ");
   13671                         TimeUtils.formatDuration(timeUsed, pw);
   13672                         pw.print(" (");
   13673                         pw.print((timeUsed*100)/realtimeSince);
   13674                         pw.println("%)");
   13675                     }
   13676                     if (r.lastCpuTime != 0) {
   13677                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   13678                         pw.print(prefix);
   13679                         pw.print("    ");
   13680                         pw.print("run cpu over ");
   13681                         TimeUtils.formatDuration(uptimeSince, pw);
   13682                         pw.print(" used ");
   13683                         TimeUtils.formatDuration(timeUsed, pw);
   13684                         pw.print(" (");
   13685                         pw.print((timeUsed*100)/uptimeSince);
   13686                         pw.println("%)");
   13687                     }
   13688                 }
   13689             }
   13690         }
   13691         return true;
   13692     }
   13693 
   13694     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
   13695             String[] args) {
   13696         ArrayList<ProcessRecord> procs;
   13697         synchronized (this) {
   13698             if (args != null && args.length > start
   13699                     && args[start].charAt(0) != '-') {
   13700                 procs = new ArrayList<ProcessRecord>();
   13701                 int pid = -1;
   13702                 try {
   13703                     pid = Integer.parseInt(args[start]);
   13704                 } catch (NumberFormatException e) {
   13705                 }
   13706                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13707                     ProcessRecord proc = mLruProcesses.get(i);
   13708                     if (proc.pid == pid) {
   13709                         procs.add(proc);
   13710                     } else if (allPkgs && proc.pkgList != null
   13711                             && proc.pkgList.containsKey(args[start])) {
   13712                         procs.add(proc);
   13713                     } else if (proc.processName.equals(args[start])) {
   13714                         procs.add(proc);
   13715                     }
   13716                 }
   13717                 if (procs.size() <= 0) {
   13718                     return null;
   13719                 }
   13720             } else {
   13721                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   13722             }
   13723         }
   13724         return procs;
   13725     }
   13726 
   13727     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   13728             PrintWriter pw, String[] args) {
   13729         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13730         if (procs == null) {
   13731             pw.println("No process found for: " + args[0]);
   13732             return;
   13733         }
   13734 
   13735         long uptime = SystemClock.uptimeMillis();
   13736         long realtime = SystemClock.elapsedRealtime();
   13737         pw.println("Applications Graphics Acceleration Info:");
   13738         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   13739 
   13740         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13741             ProcessRecord r = procs.get(i);
   13742             if (r.thread != null) {
   13743                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   13744                 pw.flush();
   13745                 try {
   13746                     TransferPipe tp = new TransferPipe();
   13747                     try {
   13748                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   13749                         tp.go(fd);
   13750                     } finally {
   13751                         tp.kill();
   13752                     }
   13753                 } catch (IOException e) {
   13754                     pw.println("Failure while dumping the app: " + r);
   13755                     pw.flush();
   13756                 } catch (RemoteException e) {
   13757                     pw.println("Got a RemoteException while dumping the app " + r);
   13758                     pw.flush();
   13759                 }
   13760             }
   13761         }
   13762     }
   13763 
   13764     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   13765         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
   13766         if (procs == null) {
   13767             pw.println("No process found for: " + args[0]);
   13768             return;
   13769         }
   13770 
   13771         pw.println("Applications Database Info:");
   13772 
   13773         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   13774             ProcessRecord r = procs.get(i);
   13775             if (r.thread != null) {
   13776                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   13777                 pw.flush();
   13778                 try {
   13779                     TransferPipe tp = new TransferPipe();
   13780                     try {
   13781                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   13782                         tp.go(fd);
   13783                     } finally {
   13784                         tp.kill();
   13785                     }
   13786                 } catch (IOException e) {
   13787                     pw.println("Failure while dumping the app: " + r);
   13788                     pw.flush();
   13789                 } catch (RemoteException e) {
   13790                     pw.println("Got a RemoteException while dumping the app " + r);
   13791                     pw.flush();
   13792                 }
   13793             }
   13794         }
   13795     }
   13796 
   13797     final static class MemItem {
   13798         final boolean isProc;
   13799         final String label;
   13800         final String shortLabel;
   13801         final long pss;
   13802         final int id;
   13803         final boolean hasActivities;
   13804         ArrayList<MemItem> subitems;
   13805 
   13806         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   13807                 boolean _hasActivities) {
   13808             isProc = true;
   13809             label = _label;
   13810             shortLabel = _shortLabel;
   13811             pss = _pss;
   13812             id = _id;
   13813             hasActivities = _hasActivities;
   13814         }
   13815 
   13816         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   13817             isProc = false;
   13818             label = _label;
   13819             shortLabel = _shortLabel;
   13820             pss = _pss;
   13821             id = _id;
   13822             hasActivities = false;
   13823         }
   13824     }
   13825 
   13826     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   13827             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   13828         if (sort && !isCompact) {
   13829             Collections.sort(items, new Comparator<MemItem>() {
   13830                 @Override
   13831                 public int compare(MemItem lhs, MemItem rhs) {
   13832                     if (lhs.pss < rhs.pss) {
   13833                         return 1;
   13834                     } else if (lhs.pss > rhs.pss) {
   13835                         return -1;
   13836                     }
   13837                     return 0;
   13838                 }
   13839             });
   13840         }
   13841 
   13842         for (int i=0; i<items.size(); i++) {
   13843             MemItem mi = items.get(i);
   13844             if (!isCompact) {
   13845                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   13846             } else if (mi.isProc) {
   13847                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   13848                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   13849                 pw.println(mi.hasActivities ? ",a" : ",e");
   13850             } else {
   13851                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   13852                 pw.println(mi.pss);
   13853             }
   13854             if (mi.subitems != null) {
   13855                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   13856                         true, isCompact);
   13857             }
   13858         }
   13859     }
   13860 
   13861     // These are in KB.
   13862     static final long[] DUMP_MEM_BUCKETS = new long[] {
   13863         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   13864         120*1024, 160*1024, 200*1024,
   13865         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   13866         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   13867     };
   13868 
   13869     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   13870             boolean stackLike) {
   13871         int start = label.lastIndexOf('.');
   13872         if (start >= 0) start++;
   13873         else start = 0;
   13874         int end = label.length();
   13875         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   13876             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   13877                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   13878                 out.append(bucket);
   13879                 out.append(stackLike ? "MB." : "MB ");
   13880                 out.append(label, start, end);
   13881                 return;
   13882             }
   13883         }
   13884         out.append(memKB/1024);
   13885         out.append(stackLike ? "MB." : "MB ");
   13886         out.append(label, start, end);
   13887     }
   13888 
   13889     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   13890             ProcessList.NATIVE_ADJ,
   13891             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
   13892             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   13893             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   13894             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   13895             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   13896             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   13897     };
   13898     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   13899             "Native",
   13900             "System", "Persistent", "Persistent Service", "Foreground",
   13901             "Visible", "Perceptible",
   13902             "Heavy Weight", "Backup",
   13903             "A Services", "Home",
   13904             "Previous", "B Services", "Cached"
   13905     };
   13906     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   13907             "native",
   13908             "sys", "pers", "persvc", "fore",
   13909             "vis", "percept",
   13910             "heavy", "backup",
   13911             "servicea", "home",
   13912             "prev", "serviceb", "cached"
   13913     };
   13914 
   13915     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   13916             long realtime, boolean isCheckinRequest, boolean isCompact) {
   13917         if (isCheckinRequest || isCompact) {
   13918             // short checkin version
   13919             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   13920         } else {
   13921             pw.println("Applications Memory Usage (kB):");
   13922             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   13923         }
   13924     }
   13925 
   13926     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   13927             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   13928         boolean dumpDetails = false;
   13929         boolean dumpFullDetails = false;
   13930         boolean dumpDalvik = false;
   13931         boolean oomOnly = false;
   13932         boolean isCompact = false;
   13933         boolean localOnly = false;
   13934         boolean packages = false;
   13935 
   13936         int opti = 0;
   13937         while (opti < args.length) {
   13938             String opt = args[opti];
   13939             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   13940                 break;
   13941             }
   13942             opti++;
   13943             if ("-a".equals(opt)) {
   13944                 dumpDetails = true;
   13945                 dumpFullDetails = true;
   13946                 dumpDalvik = true;
   13947             } else if ("-d".equals(opt)) {
   13948                 dumpDalvik = true;
   13949             } else if ("-c".equals(opt)) {
   13950                 isCompact = true;
   13951             } else if ("--oom".equals(opt)) {
   13952                 oomOnly = true;
   13953             } else if ("--local".equals(opt)) {
   13954                 localOnly = true;
   13955             } else if ("--package".equals(opt)) {
   13956                 packages = true;
   13957             } else if ("-h".equals(opt)) {
   13958                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   13959                 pw.println("  -a: include all available information for each process.");
   13960                 pw.println("  -d: include dalvik details when dumping process details.");
   13961                 pw.println("  -c: dump in a compact machine-parseable representation.");
   13962                 pw.println("  --oom: only show processes organized by oom adj.");
   13963                 pw.println("  --local: only collect details locally, don't call process.");
   13964                 pw.println("  --package: interpret process arg as package, dumping all");
   13965                 pw.println("             processes that have loaded that package.");
   13966                 pw.println("If [process] is specified it can be the name or ");
   13967                 pw.println("pid of a specific process to dump.");
   13968                 return;
   13969             } else {
   13970                 pw.println("Unknown argument: " + opt + "; use -h for help");
   13971             }
   13972         }
   13973 
   13974         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   13975         long uptime = SystemClock.uptimeMillis();
   13976         long realtime = SystemClock.elapsedRealtime();
   13977         final long[] tmpLong = new long[1];
   13978 
   13979         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
   13980         if (procs == null) {
   13981             // No Java processes.  Maybe they want to print a native process.
   13982             if (args != null && args.length > opti
   13983                     && args[opti].charAt(0) != '-') {
   13984                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   13985                         = new ArrayList<ProcessCpuTracker.Stats>();
   13986                 updateCpuStatsNow();
   13987                 int findPid = -1;
   13988                 try {
   13989                     findPid = Integer.parseInt(args[opti]);
   13990                 } catch (NumberFormatException e) {
   13991                 }
   13992                 synchronized (mProcessCpuTracker) {
   13993                     final int N = mProcessCpuTracker.countStats();
   13994                     for (int i=0; i<N; i++) {
   13995                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   13996                         if (st.pid == findPid || (st.baseName != null
   13997                                 && st.baseName.equals(args[opti]))) {
   13998                             nativeProcs.add(st);
   13999                         }
   14000                     }
   14001                 }
   14002                 if (nativeProcs.size() > 0) {
   14003                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   14004                             isCompact);
   14005                     Debug.MemoryInfo mi = null;
   14006                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   14007                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   14008                         final int pid = r.pid;
   14009                         if (!isCheckinRequest && dumpDetails) {
   14010                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   14011                         }
   14012                         if (mi == null) {
   14013                             mi = new Debug.MemoryInfo();
   14014                         }
   14015                         if (dumpDetails || (!brief && !oomOnly)) {
   14016                             Debug.getMemoryInfo(pid, mi);
   14017                         } else {
   14018                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   14019                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   14020                         }
   14021                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14022                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   14023                         if (isCheckinRequest) {
   14024                             pw.println();
   14025                         }
   14026                     }
   14027                     return;
   14028                 }
   14029             }
   14030             pw.println("No process found for: " + args[opti]);
   14031             return;
   14032         }
   14033 
   14034         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
   14035             dumpDetails = true;
   14036         }
   14037 
   14038         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   14039 
   14040         String[] innerArgs = new String[args.length-opti];
   14041         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   14042 
   14043         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   14044         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   14045         long nativePss=0, dalvikPss=0, otherPss=0;
   14046         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   14047 
   14048         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   14049         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   14050                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   14051 
   14052         long totalPss = 0;
   14053         long cachedPss = 0;
   14054 
   14055         Debug.MemoryInfo mi = null;
   14056         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   14057             final ProcessRecord r = procs.get(i);
   14058             final IApplicationThread thread;
   14059             final int pid;
   14060             final int oomAdj;
   14061             final boolean hasActivities;
   14062             synchronized (this) {
   14063                 thread = r.thread;
   14064                 pid = r.pid;
   14065                 oomAdj = r.getSetAdjWithServices();
   14066                 hasActivities = r.activities.size() > 0;
   14067             }
   14068             if (thread != null) {
   14069                 if (!isCheckinRequest && dumpDetails) {
   14070                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   14071                 }
   14072                 if (mi == null) {
   14073                     mi = new Debug.MemoryInfo();
   14074                 }
   14075                 if (dumpDetails || (!brief && !oomOnly)) {
   14076                     Debug.getMemoryInfo(pid, mi);
   14077                 } else {
   14078                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   14079                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   14080                 }
   14081                 if (dumpDetails) {
   14082                     if (localOnly) {
   14083                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   14084                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
   14085                         if (isCheckinRequest) {
   14086                             pw.println();
   14087                         }
   14088                     } else {
   14089                         try {
   14090                             pw.flush();
   14091                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   14092                                     dumpDalvik, innerArgs);
   14093                         } catch (RemoteException e) {
   14094                             if (!isCheckinRequest) {
   14095                                 pw.println("Got RemoteException!");
   14096                                 pw.flush();
   14097                             }
   14098                         }
   14099                     }
   14100                 }
   14101 
   14102                 final long myTotalPss = mi.getTotalPss();
   14103                 final long myTotalUss = mi.getTotalUss();
   14104 
   14105                 synchronized (this) {
   14106                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   14107                         // Record this for posterity if the process has been stable.
   14108                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   14109                     }
   14110                 }
   14111 
   14112                 if (!isCheckinRequest && mi != null) {
   14113                     totalPss += myTotalPss;
   14114                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   14115                             (hasActivities ? " / activities)" : ")"),
   14116                             r.processName, myTotalPss, pid, hasActivities);
   14117                     procMems.add(pssItem);
   14118                     procMemsMap.put(pid, pssItem);
   14119 
   14120                     nativePss += mi.nativePss;
   14121                     dalvikPss += mi.dalvikPss;
   14122                     otherPss += mi.otherPss;
   14123                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14124                         long mem = mi.getOtherPss(j);
   14125                         miscPss[j] += mem;
   14126                         otherPss -= mem;
   14127                     }
   14128 
   14129                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14130                         cachedPss += myTotalPss;
   14131                     }
   14132 
   14133                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   14134                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   14135                                 || oomIndex == (oomPss.length-1)) {
   14136                             oomPss[oomIndex] += myTotalPss;
   14137                             if (oomProcs[oomIndex] == null) {
   14138                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   14139                             }
   14140                             oomProcs[oomIndex].add(pssItem);
   14141                             break;
   14142                         }
   14143                     }
   14144                 }
   14145             }
   14146         }
   14147 
   14148         long nativeProcTotalPss = 0;
   14149 
   14150         if (!isCheckinRequest && procs.size() > 1 && !packages) {
   14151             // If we are showing aggregations, also look for native processes to
   14152             // include so that our aggregations are more accurate.
   14153             updateCpuStatsNow();
   14154             synchronized (mProcessCpuTracker) {
   14155                 final int N = mProcessCpuTracker.countStats();
   14156                 for (int i=0; i<N; i++) {
   14157                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   14158                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   14159                         if (mi == null) {
   14160                             mi = new Debug.MemoryInfo();
   14161                         }
   14162                         if (!brief && !oomOnly) {
   14163                             Debug.getMemoryInfo(st.pid, mi);
   14164                         } else {
   14165                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
   14166                             mi.nativePrivateDirty = (int)tmpLong[0];
   14167                         }
   14168 
   14169                         final long myTotalPss = mi.getTotalPss();
   14170                         totalPss += myTotalPss;
   14171                         nativeProcTotalPss += myTotalPss;
   14172 
   14173                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   14174                                 st.name, myTotalPss, st.pid, false);
   14175                         procMems.add(pssItem);
   14176 
   14177                         nativePss += mi.nativePss;
   14178                         dalvikPss += mi.dalvikPss;
   14179                         otherPss += mi.otherPss;
   14180                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14181                             long mem = mi.getOtherPss(j);
   14182                             miscPss[j] += mem;
   14183                             otherPss -= mem;
   14184                         }
   14185                         oomPss[0] += myTotalPss;
   14186                         if (oomProcs[0] == null) {
   14187                             oomProcs[0] = new ArrayList<MemItem>();
   14188                         }
   14189                         oomProcs[0].add(pssItem);
   14190                     }
   14191                 }
   14192             }
   14193 
   14194             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   14195 
   14196             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   14197             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   14198             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   14199             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   14200                 String label = Debug.MemoryInfo.getOtherLabel(j);
   14201                 catMems.add(new MemItem(label, label, miscPss[j], j));
   14202             }
   14203 
   14204             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   14205             for (int j=0; j<oomPss.length; j++) {
   14206                 if (oomPss[j] != 0) {
   14207                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   14208                             : DUMP_MEM_OOM_LABEL[j];
   14209                     MemItem item = new MemItem(label, label, oomPss[j],
   14210                             DUMP_MEM_OOM_ADJ[j]);
   14211                     item.subitems = oomProcs[j];
   14212                     oomMems.add(item);
   14213                 }
   14214             }
   14215 
   14216             if (!brief && !oomOnly && !isCompact) {
   14217                 pw.println();
   14218                 pw.println("Total PSS by process:");
   14219                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   14220                 pw.println();
   14221             }
   14222             if (!isCompact) {
   14223                 pw.println("Total PSS by OOM adjustment:");
   14224             }
   14225             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   14226             if (!brief && !oomOnly) {
   14227                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   14228                 if (!isCompact) {
   14229                     out.println();
   14230                     out.println("Total PSS by category:");
   14231                 }
   14232                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   14233             }
   14234             if (!isCompact) {
   14235                 pw.println();
   14236             }
   14237             MemInfoReader memInfo = new MemInfoReader();
   14238             memInfo.readMemInfo();
   14239             if (nativeProcTotalPss > 0) {
   14240                 synchronized (this) {
   14241                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
   14242                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
   14243                             memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
   14244                             nativeProcTotalPss);
   14245                 }
   14246             }
   14247             if (!brief) {
   14248                 if (!isCompact) {
   14249                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   14250                     pw.print(" kB (status ");
   14251                     switch (mLastMemoryLevel) {
   14252                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
   14253                             pw.println("normal)");
   14254                             break;
   14255                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
   14256                             pw.println("moderate)");
   14257                             break;
   14258                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
   14259                             pw.println("low)");
   14260                             break;
   14261                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   14262                             pw.println("critical)");
   14263                             break;
   14264                         default:
   14265                             pw.print(mLastMemoryLevel);
   14266                             pw.println(")");
   14267                             break;
   14268                     }
   14269                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   14270                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   14271                             pw.print(cachedPss); pw.print(" cached pss + ");
   14272                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
   14273                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   14274                 } else {
   14275                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   14276                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   14277                             + memInfo.getFreeSizeKb()); pw.print(",");
   14278                     pw.println(totalPss - cachedPss);
   14279                 }
   14280             }
   14281             if (!isCompact) {
   14282                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   14283                         + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
   14284                         + memInfo.getSlabSizeKb()); pw.print(" kB (");
   14285                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   14286                         pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
   14287                         pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
   14288                         pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
   14289                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   14290                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   14291                         - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
   14292                         - memInfo.getSlabSizeKb()); pw.println(" kB");
   14293             }
   14294             if (!brief) {
   14295                 if (memInfo.getZramTotalSizeKb() != 0) {
   14296                     if (!isCompact) {
   14297                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   14298                                 pw.print(" kB physical used for ");
   14299                                 pw.print(memInfo.getSwapTotalSizeKb()
   14300                                         - memInfo.getSwapFreeSizeKb());
   14301                                 pw.print(" kB in swap (");
   14302                                 pw.print(memInfo.getSwapTotalSizeKb());
   14303                                 pw.println(" kB total swap)");
   14304                     } else {
   14305                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   14306                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   14307                                 pw.println(memInfo.getSwapFreeSizeKb());
   14308                     }
   14309                 }
   14310                 final int[] SINGLE_LONG_FORMAT = new int[] {
   14311                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   14312                 };
   14313                 long[] longOut = new long[1];
   14314                 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   14315                         SINGLE_LONG_FORMAT, null, longOut, null);
   14316                 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   14317                 longOut[0] = 0;
   14318                 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   14319                         SINGLE_LONG_FORMAT, null, longOut, null);
   14320                 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   14321                 longOut[0] = 0;
   14322                 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   14323                         SINGLE_LONG_FORMAT, null, longOut, null);
   14324                 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   14325                 longOut[0] = 0;
   14326                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   14327                         SINGLE_LONG_FORMAT, null, longOut, null);
   14328                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   14329                 if (!isCompact) {
   14330                     if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
   14331                         pw.print("      KSM: "); pw.print(sharing);
   14332                                 pw.print(" kB saved from shared ");
   14333                                 pw.print(shared); pw.println(" kB");
   14334                         pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   14335                                 pw.print(voltile); pw.println(" kB volatile");
   14336                     }
   14337                     pw.print("   Tuning: ");
   14338                     pw.print(ActivityManager.staticGetMemoryClass());
   14339                     pw.print(" (large ");
   14340                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14341                     pw.print("), oom ");
   14342                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14343                     pw.print(" kB");
   14344                     pw.print(", restore limit ");
   14345                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   14346                     pw.print(" kB");
   14347                     if (ActivityManager.isLowRamDeviceStatic()) {
   14348                         pw.print(" (low-ram)");
   14349                     }
   14350                     if (ActivityManager.isHighEndGfx()) {
   14351                         pw.print(" (high-end-gfx)");
   14352                     }
   14353                     pw.println();
   14354                 } else {
   14355                     pw.print("ksm,"); pw.print(sharing); pw.print(",");
   14356                     pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
   14357                     pw.println(voltile);
   14358                     pw.print("tuning,");
   14359                     pw.print(ActivityManager.staticGetMemoryClass());
   14360                     pw.print(',');
   14361                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   14362                     pw.print(',');
   14363                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   14364                     if (ActivityManager.isLowRamDeviceStatic()) {
   14365                         pw.print(",low-ram");
   14366                     }
   14367                     if (ActivityManager.isHighEndGfx()) {
   14368                         pw.print(",high-end-gfx");
   14369                     }
   14370                     pw.println();
   14371                 }
   14372             }
   14373         }
   14374     }
   14375 
   14376     /**
   14377      * Searches array of arguments for the specified string
   14378      * @param args array of argument strings
   14379      * @param value value to search for
   14380      * @return true if the value is contained in the array
   14381      */
   14382     private static boolean scanArgs(String[] args, String value) {
   14383         if (args != null) {
   14384             for (String arg : args) {
   14385                 if (value.equals(arg)) {
   14386                     return true;
   14387                 }
   14388             }
   14389         }
   14390         return false;
   14391     }
   14392 
   14393     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   14394             ContentProviderRecord cpr, boolean always) {
   14395         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   14396 
   14397         if (!inLaunching || always) {
   14398             synchronized (cpr) {
   14399                 cpr.launchingApp = null;
   14400                 cpr.notifyAll();
   14401             }
   14402             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   14403             String names[] = cpr.info.authority.split(";");
   14404             for (int j = 0; j < names.length; j++) {
   14405                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   14406             }
   14407         }
   14408 
   14409         for (int i=0; i<cpr.connections.size(); i++) {
   14410             ContentProviderConnection conn = cpr.connections.get(i);
   14411             if (conn.waiting) {
   14412                 // If this connection is waiting for the provider, then we don't
   14413                 // need to mess with its process unless we are always removing
   14414                 // or for some reason the provider is not currently launching.
   14415                 if (inLaunching && !always) {
   14416                     continue;
   14417                 }
   14418             }
   14419             ProcessRecord capp = conn.client;
   14420             conn.dead = true;
   14421             if (conn.stableCount > 0) {
   14422                 if (!capp.persistent && capp.thread != null
   14423                         && capp.pid != 0
   14424                         && capp.pid != MY_PID) {
   14425                     capp.kill("depends on provider "
   14426                             + cpr.name.flattenToShortString()
   14427                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
   14428                 }
   14429             } else if (capp.thread != null && conn.provider.provider != null) {
   14430                 try {
   14431                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   14432                 } catch (RemoteException e) {
   14433                 }
   14434                 // In the protocol here, we don't expect the client to correctly
   14435                 // clean up this connection, we'll just remove it.
   14436                 cpr.connections.remove(i);
   14437                 conn.client.conProviders.remove(conn);
   14438             }
   14439         }
   14440 
   14441         if (inLaunching && always) {
   14442             mLaunchingProviders.remove(cpr);
   14443         }
   14444         return inLaunching;
   14445     }
   14446 
   14447     /**
   14448      * Main code for cleaning up a process when it has gone away.  This is
   14449      * called both as a result of the process dying, or directly when stopping
   14450      * a process when running in single process mode.
   14451      *
   14452      * @return Returns true if the given process has been restarted, so the
   14453      * app that was passed in must remain on the process lists.
   14454      */
   14455     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
   14456             boolean restarting, boolean allowRestart, int index) {
   14457         if (index >= 0) {
   14458             removeLruProcessLocked(app);
   14459             ProcessList.remove(app.pid);
   14460         }
   14461 
   14462         mProcessesToGc.remove(app);
   14463         mPendingPssProcesses.remove(app);
   14464 
   14465         // Dismiss any open dialogs.
   14466         if (app.crashDialog != null && !app.forceCrashReport) {
   14467             app.crashDialog.dismiss();
   14468             app.crashDialog = null;
   14469         }
   14470         if (app.anrDialog != null) {
   14471             app.anrDialog.dismiss();
   14472             app.anrDialog = null;
   14473         }
   14474         if (app.waitDialog != null) {
   14475             app.waitDialog.dismiss();
   14476             app.waitDialog = null;
   14477         }
   14478 
   14479         app.crashing = false;
   14480         app.notResponding = false;
   14481 
   14482         app.resetPackageList(mProcessStats);
   14483         app.unlinkDeathRecipient();
   14484         app.makeInactive(mProcessStats);
   14485         app.waitingToKill = null;
   14486         app.forcingToForeground = null;
   14487         updateProcessForegroundLocked(app, false, false);
   14488         app.foregroundActivities = false;
   14489         app.hasShownUi = false;
   14490         app.treatLikeActivity = false;
   14491         app.hasAboveClient = false;
   14492         app.hasClientActivities = false;
   14493 
   14494         mServices.killServicesLocked(app, allowRestart);
   14495 
   14496         boolean restart = false;
   14497 
   14498         // Remove published content providers.
   14499         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   14500             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   14501             final boolean always = app.bad || !allowRestart;
   14502             if (removeDyingProviderLocked(app, cpr, always) || always) {
   14503                 // We left the provider in the launching list, need to
   14504                 // restart it.
   14505                 restart = true;
   14506             }
   14507 
   14508             cpr.provider = null;
   14509             cpr.proc = null;
   14510         }
   14511         app.pubProviders.clear();
   14512 
   14513         // Take care of any launching providers waiting for this process.
   14514         if (checkAppInLaunchingProvidersLocked(app, false)) {
   14515             restart = true;
   14516         }
   14517 
   14518         // Unregister from connected content providers.
   14519         if (!app.conProviders.isEmpty()) {
   14520             for (int i=0; i<app.conProviders.size(); i++) {
   14521                 ContentProviderConnection conn = app.conProviders.get(i);
   14522                 conn.provider.connections.remove(conn);
   14523             }
   14524             app.conProviders.clear();
   14525         }
   14526 
   14527         // At this point there may be remaining entries in mLaunchingProviders
   14528         // where we were the only one waiting, so they are no longer of use.
   14529         // Look for these and clean up if found.
   14530         // XXX Commented out for now.  Trying to figure out a way to reproduce
   14531         // the actual situation to identify what is actually going on.
   14532         if (false) {
   14533             for (int i=0; i<mLaunchingProviders.size(); i++) {
   14534                 ContentProviderRecord cpr = (ContentProviderRecord)
   14535                         mLaunchingProviders.get(i);
   14536                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   14537                     synchronized (cpr) {
   14538                         cpr.launchingApp = null;
   14539                         cpr.notifyAll();
   14540                     }
   14541                 }
   14542             }
   14543         }
   14544 
   14545         skipCurrentReceiverLocked(app);
   14546 
   14547         // Unregister any receivers.
   14548         for (int i=app.receivers.size()-1; i>=0; i--) {
   14549             removeReceiverLocked(app.receivers.valueAt(i));
   14550         }
   14551         app.receivers.clear();
   14552 
   14553         // If the app is undergoing backup, tell the backup manager about it
   14554         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   14555             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   14556                     + mBackupTarget.appInfo + " died during backup");
   14557             try {
   14558                 IBackupManager bm = IBackupManager.Stub.asInterface(
   14559                         ServiceManager.getService(Context.BACKUP_SERVICE));
   14560                 bm.agentDisconnected(app.info.packageName);
   14561             } catch (RemoteException e) {
   14562                 // can't happen; backup manager is local
   14563             }
   14564         }
   14565 
   14566         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   14567             ProcessChangeItem item = mPendingProcessChanges.get(i);
   14568             if (item.pid == app.pid) {
   14569                 mPendingProcessChanges.remove(i);
   14570                 mAvailProcessChanges.add(item);
   14571             }
   14572         }
   14573         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   14574 
   14575         // If the caller is restarting this app, then leave it in its
   14576         // current lists and let the caller take care of it.
   14577         if (restarting) {
   14578             return false;
   14579         }
   14580 
   14581         if (!app.persistent || app.isolated) {
   14582             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   14583                     "Removing non-persistent process during cleanup: " + app);
   14584             mProcessNames.remove(app.processName, app.uid);
   14585             mIsolatedProcesses.remove(app.uid);
   14586             if (mHeavyWeightProcess == app) {
   14587                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   14588                         mHeavyWeightProcess.userId, 0));
   14589                 mHeavyWeightProcess = null;
   14590             }
   14591         } else if (!app.removed) {
   14592             // This app is persistent, so we need to keep its record around.
   14593             // If it is not already on the pending app list, add it there
   14594             // and start a new process for it.
   14595             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   14596                 mPersistentStartingProcesses.add(app);
   14597                 restart = true;
   14598             }
   14599         }
   14600         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   14601                 "Clean-up removing on hold: " + app);
   14602         mProcessesOnHold.remove(app);
   14603 
   14604         if (app == mHomeProcess) {
   14605             mHomeProcess = null;
   14606         }
   14607         if (app == mPreviousProcess) {
   14608             mPreviousProcess = null;
   14609         }
   14610 
   14611         if (restart && !app.isolated) {
   14612             // We have components that still need to be running in the
   14613             // process, so re-launch it.
   14614             if (index < 0) {
   14615                 ProcessList.remove(app.pid);
   14616             }
   14617             mProcessNames.put(app.processName, app.uid, app);
   14618             startProcessLocked(app, "restart", app.processName);
   14619             return true;
   14620         } else if (app.pid > 0 && app.pid != MY_PID) {
   14621             // Goodbye!
   14622             boolean removed;
   14623             synchronized (mPidsSelfLocked) {
   14624                 mPidsSelfLocked.remove(app.pid);
   14625                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   14626             }
   14627             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
   14628             if (app.isolated) {
   14629                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
   14630             }
   14631             app.setPid(0);
   14632         }
   14633         return false;
   14634     }
   14635 
   14636     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   14637         // Look through the content providers we are waiting to have launched,
   14638         // and if any run in this process then either schedule a restart of
   14639         // the process or kill the client waiting for it if this process has
   14640         // gone bad.
   14641         int NL = mLaunchingProviders.size();
   14642         boolean restart = false;
   14643         for (int i=0; i<NL; i++) {
   14644             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   14645             if (cpr.launchingApp == app) {
   14646                 if (!alwaysBad && !app.bad) {
   14647                     restart = true;
   14648                 } else {
   14649                     removeDyingProviderLocked(app, cpr, true);
   14650                     // cpr should have been removed from mLaunchingProviders
   14651                     NL = mLaunchingProviders.size();
   14652                     i--;
   14653                 }
   14654             }
   14655         }
   14656         return restart;
   14657     }
   14658 
   14659     // =========================================================
   14660     // SERVICES
   14661     // =========================================================
   14662 
   14663     @Override
   14664     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   14665             int flags) {
   14666         enforceNotIsolatedCaller("getServices");
   14667         synchronized (this) {
   14668             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   14669         }
   14670     }
   14671 
   14672     @Override
   14673     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   14674         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   14675         synchronized (this) {
   14676             return mServices.getRunningServiceControlPanelLocked(name);
   14677         }
   14678     }
   14679 
   14680     @Override
   14681     public ComponentName startService(IApplicationThread caller, Intent service,
   14682             String resolvedType, int userId) {
   14683         enforceNotIsolatedCaller("startService");
   14684         // Refuse possible leaked file descriptors
   14685         if (service != null && service.hasFileDescriptors() == true) {
   14686             throw new IllegalArgumentException("File descriptors passed in Intent");
   14687         }
   14688 
   14689         if (DEBUG_SERVICE)
   14690             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   14691         synchronized(this) {
   14692             final int callingPid = Binder.getCallingPid();
   14693             final int callingUid = Binder.getCallingUid();
   14694             final long origId = Binder.clearCallingIdentity();
   14695             ComponentName res = mServices.startServiceLocked(caller, service,
   14696                     resolvedType, callingPid, callingUid, userId);
   14697             Binder.restoreCallingIdentity(origId);
   14698             return res;
   14699         }
   14700     }
   14701 
   14702     ComponentName startServiceInPackage(int uid,
   14703             Intent service, String resolvedType, int userId) {
   14704         synchronized(this) {
   14705             if (DEBUG_SERVICE)
   14706                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   14707             final long origId = Binder.clearCallingIdentity();
   14708             ComponentName res = mServices.startServiceLocked(null, service,
   14709                     resolvedType, -1, uid, userId);
   14710             Binder.restoreCallingIdentity(origId);
   14711             return res;
   14712         }
   14713     }
   14714 
   14715     @Override
   14716     public int stopService(IApplicationThread caller, Intent service,
   14717             String resolvedType, int userId) {
   14718         enforceNotIsolatedCaller("stopService");
   14719         // Refuse possible leaked file descriptors
   14720         if (service != null && service.hasFileDescriptors() == true) {
   14721             throw new IllegalArgumentException("File descriptors passed in Intent");
   14722         }
   14723 
   14724         synchronized(this) {
   14725             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   14726         }
   14727     }
   14728 
   14729     @Override
   14730     public IBinder peekService(Intent service, String resolvedType) {
   14731         enforceNotIsolatedCaller("peekService");
   14732         // Refuse possible leaked file descriptors
   14733         if (service != null && service.hasFileDescriptors() == true) {
   14734             throw new IllegalArgumentException("File descriptors passed in Intent");
   14735         }
   14736         synchronized(this) {
   14737             return mServices.peekServiceLocked(service, resolvedType);
   14738         }
   14739     }
   14740 
   14741     @Override
   14742     public boolean stopServiceToken(ComponentName className, IBinder token,
   14743             int startId) {
   14744         synchronized(this) {
   14745             return mServices.stopServiceTokenLocked(className, token, startId);
   14746         }
   14747     }
   14748 
   14749     @Override
   14750     public void setServiceForeground(ComponentName className, IBinder token,
   14751             int id, Notification notification, boolean removeNotification) {
   14752         synchronized(this) {
   14753             mServices.setServiceForegroundLocked(className, token, id, notification,
   14754                     removeNotification);
   14755         }
   14756     }
   14757 
   14758     @Override
   14759     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   14760             boolean requireFull, String name, String callerPackage) {
   14761         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
   14762                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
   14763     }
   14764 
   14765     int unsafeConvertIncomingUser(int userId) {
   14766         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
   14767                 ? mCurrentUserId : userId;
   14768     }
   14769 
   14770     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   14771             int allowMode, String name, String callerPackage) {
   14772         final int callingUserId = UserHandle.getUserId(callingUid);
   14773         if (callingUserId == userId) {
   14774             return userId;
   14775         }
   14776 
   14777         // Note that we may be accessing mCurrentUserId outside of a lock...
   14778         // shouldn't be a big deal, if this is being called outside
   14779         // of a locked context there is intrinsically a race with
   14780         // the value the caller will receive and someone else changing it.
   14781         // We assume that USER_CURRENT_OR_SELF will use the current user; later
   14782         // we will switch to the calling user if access to the current user fails.
   14783         int targetUserId = unsafeConvertIncomingUser(userId);
   14784 
   14785         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   14786             final boolean allow;
   14787             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
   14788                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
   14789                 // If the caller has this permission, they always pass go.  And collect $200.
   14790                 allow = true;
   14791             } else if (allowMode == ALLOW_FULL_ONLY) {
   14792                 // We require full access, sucks to be you.
   14793                 allow = false;
   14794             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
   14795                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
   14796                 // If the caller does not have either permission, they are always doomed.
   14797                 allow = false;
   14798             } else if (allowMode == ALLOW_NON_FULL) {
   14799                 // We are blanket allowing non-full access, you lucky caller!
   14800                 allow = true;
   14801             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
   14802                 // We may or may not allow this depending on whether the two users are
   14803                 // in the same profile.
   14804                 synchronized (mUserProfileGroupIdsSelfLocked) {
   14805                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
   14806                             UserInfo.NO_PROFILE_GROUP_ID);
   14807                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
   14808                             UserInfo.NO_PROFILE_GROUP_ID);
   14809                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
   14810                             && callingProfile == targetProfile;
   14811                 }
   14812             } else {
   14813                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
   14814             }
   14815             if (!allow) {
   14816                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   14817                     // In this case, they would like to just execute as their
   14818                     // owner user instead of failing.
   14819                     targetUserId = callingUserId;
   14820                 } else {
   14821                     StringBuilder builder = new StringBuilder(128);
   14822                     builder.append("Permission Denial: ");
   14823                     builder.append(name);
   14824                     if (callerPackage != null) {
   14825                         builder.append(" from ");
   14826                         builder.append(callerPackage);
   14827                     }
   14828                     builder.append(" asks to run as user ");
   14829                     builder.append(userId);
   14830                     builder.append(" but is calling from user ");
   14831                     builder.append(UserHandle.getUserId(callingUid));
   14832                     builder.append("; this requires ");
   14833                     builder.append(INTERACT_ACROSS_USERS_FULL);
   14834                     if (allowMode != ALLOW_FULL_ONLY) {
   14835                         builder.append(" or ");
   14836                         builder.append(INTERACT_ACROSS_USERS);
   14837                     }
   14838                     String msg = builder.toString();
   14839                     Slog.w(TAG, msg);
   14840                     throw new SecurityException(msg);
   14841                 }
   14842             }
   14843         }
   14844         if (!allowAll && targetUserId < 0) {
   14845             throw new IllegalArgumentException(
   14846                     "Call does not support special user #" + targetUserId);
   14847         }
   14848         // Check shell permission
   14849         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
   14850             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
   14851                     targetUserId)) {
   14852                 throw new SecurityException("Shell does not have permission to access user "
   14853                         + targetUserId + "\n " + Debug.getCallers(3));
   14854             }
   14855         }
   14856         return targetUserId;
   14857     }
   14858 
   14859     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   14860             String className, int flags) {
   14861         boolean result = false;
   14862         // For apps that don't have pre-defined UIDs, check for permission
   14863         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   14864             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   14865                 if (ActivityManager.checkUidPermission(
   14866                         INTERACT_ACROSS_USERS,
   14867                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   14868                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   14869                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   14870                             + " requests FLAG_SINGLE_USER, but app does not hold "
   14871                             + INTERACT_ACROSS_USERS;
   14872                     Slog.w(TAG, msg);
   14873                     throw new SecurityException(msg);
   14874                 }
   14875                 // Permission passed
   14876                 result = true;
   14877             }
   14878         } else if ("system".equals(componentProcessName)) {
   14879             result = true;
   14880         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
   14881             // Phone app and persistent apps are allowed to export singleuser providers.
   14882             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
   14883                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   14884         }
   14885         if (DEBUG_MU) {
   14886             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   14887                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   14888         }
   14889         return result;
   14890     }
   14891 
   14892     /**
   14893      * Checks to see if the caller is in the same app as the singleton
   14894      * component, or the component is in a special app. It allows special apps
   14895      * to export singleton components but prevents exporting singleton
   14896      * components for regular apps.
   14897      */
   14898     boolean isValidSingletonCall(int callingUid, int componentUid) {
   14899         int componentAppId = UserHandle.getAppId(componentUid);
   14900         return UserHandle.isSameApp(callingUid, componentUid)
   14901                 || componentAppId == Process.SYSTEM_UID
   14902                 || componentAppId == Process.PHONE_UID
   14903                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
   14904                         == PackageManager.PERMISSION_GRANTED;
   14905     }
   14906 
   14907     public int bindService(IApplicationThread caller, IBinder token,
   14908             Intent service, String resolvedType,
   14909             IServiceConnection connection, int flags, int userId) {
   14910         enforceNotIsolatedCaller("bindService");
   14911 
   14912         // Refuse possible leaked file descriptors
   14913         if (service != null && service.hasFileDescriptors() == true) {
   14914             throw new IllegalArgumentException("File descriptors passed in Intent");
   14915         }
   14916 
   14917         synchronized(this) {
   14918             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   14919                     connection, flags, userId);
   14920         }
   14921     }
   14922 
   14923     public boolean unbindService(IServiceConnection connection) {
   14924         synchronized (this) {
   14925             return mServices.unbindServiceLocked(connection);
   14926         }
   14927     }
   14928 
   14929     public void publishService(IBinder token, Intent intent, IBinder service) {
   14930         // Refuse possible leaked file descriptors
   14931         if (intent != null && intent.hasFileDescriptors() == true) {
   14932             throw new IllegalArgumentException("File descriptors passed in Intent");
   14933         }
   14934 
   14935         synchronized(this) {
   14936             if (!(token instanceof ServiceRecord)) {
   14937                 throw new IllegalArgumentException("Invalid service token");
   14938             }
   14939             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   14940         }
   14941     }
   14942 
   14943     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   14944         // Refuse possible leaked file descriptors
   14945         if (intent != null && intent.hasFileDescriptors() == true) {
   14946             throw new IllegalArgumentException("File descriptors passed in Intent");
   14947         }
   14948 
   14949         synchronized(this) {
   14950             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   14951         }
   14952     }
   14953 
   14954     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   14955         synchronized(this) {
   14956             if (!(token instanceof ServiceRecord)) {
   14957                 throw new IllegalArgumentException("Invalid service token");
   14958             }
   14959             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   14960         }
   14961     }
   14962 
   14963     // =========================================================
   14964     // BACKUP AND RESTORE
   14965     // =========================================================
   14966 
   14967     // Cause the target app to be launched if necessary and its backup agent
   14968     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   14969     // activity manager to announce its creation.
   14970     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   14971         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   14972         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
   14973 
   14974         synchronized(this) {
   14975             // !!! TODO: currently no check here that we're already bound
   14976             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   14977             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14978             synchronized (stats) {
   14979                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   14980             }
   14981 
   14982             // Backup agent is now in use, its package can't be stopped.
   14983             try {
   14984                 AppGlobals.getPackageManager().setPackageStoppedState(
   14985                         app.packageName, false, UserHandle.getUserId(app.uid));
   14986             } catch (RemoteException e) {
   14987             } catch (IllegalArgumentException e) {
   14988                 Slog.w(TAG, "Failed trying to unstop package "
   14989                         + app.packageName + ": " + e);
   14990             }
   14991 
   14992             BackupRecord r = new BackupRecord(ss, app, backupMode);
   14993             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   14994                     ? new ComponentName(app.packageName, app.backupAgentName)
   14995                     : new ComponentName("android", "FullBackupAgent");
   14996             // startProcessLocked() returns existing proc's record if it's already running
   14997             ProcessRecord proc = startProcessLocked(app.processName, app,
   14998                     false, 0, "backup", hostingName, false, false, false);
   14999             if (proc == null) {
   15000                 Slog.e(TAG, "Unable to start backup agent process " + r);
   15001                 return false;
   15002             }
   15003 
   15004             r.app = proc;
   15005             mBackupTarget = r;
   15006             mBackupAppName = app.packageName;
   15007 
   15008             // Try not to kill the process during backup
   15009             updateOomAdjLocked(proc);
   15010 
   15011             // If the process is already attached, schedule the creation of the backup agent now.
   15012             // If it is not yet live, this will be done when it attaches to the framework.
   15013             if (proc.thread != null) {
   15014                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   15015                 try {
   15016                     proc.thread.scheduleCreateBackupAgent(app,
   15017                             compatibilityInfoForPackageLocked(app), backupMode);
   15018                 } catch (RemoteException e) {
   15019                     // Will time out on the backup manager side
   15020                 }
   15021             } else {
   15022                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   15023             }
   15024             // Invariants: at this point, the target app process exists and the application
   15025             // is either already running or in the process of coming up.  mBackupTarget and
   15026             // mBackupAppName describe the app, so that when it binds back to the AM we
   15027             // know that it's scheduled for a backup-agent operation.
   15028         }
   15029 
   15030         return true;
   15031     }
   15032 
   15033     @Override
   15034     public void clearPendingBackup() {
   15035         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   15036         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   15037 
   15038         synchronized (this) {
   15039             mBackupTarget = null;
   15040             mBackupAppName = null;
   15041         }
   15042     }
   15043 
   15044     // A backup agent has just come up
   15045     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   15046         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   15047                 + " = " + agent);
   15048 
   15049         synchronized(this) {
   15050             if (!agentPackageName.equals(mBackupAppName)) {
   15051                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   15052                 return;
   15053             }
   15054         }
   15055 
   15056         long oldIdent = Binder.clearCallingIdentity();
   15057         try {
   15058             IBackupManager bm = IBackupManager.Stub.asInterface(
   15059                     ServiceManager.getService(Context.BACKUP_SERVICE));
   15060             bm.agentConnected(agentPackageName, agent);
   15061         } catch (RemoteException e) {
   15062             // can't happen; the backup manager service is local
   15063         } catch (Exception e) {
   15064             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   15065             e.printStackTrace();
   15066         } finally {
   15067             Binder.restoreCallingIdentity(oldIdent);
   15068         }
   15069     }
   15070 
   15071     // done with this agent
   15072     public void unbindBackupAgent(ApplicationInfo appInfo) {
   15073         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   15074         if (appInfo == null) {
   15075             Slog.w(TAG, "unbind backup agent for null app");
   15076             return;
   15077         }
   15078 
   15079         synchronized(this) {
   15080             try {
   15081                 if (mBackupAppName == null) {
   15082                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   15083                     return;
   15084                 }
   15085 
   15086                 if (!mBackupAppName.equals(appInfo.packageName)) {
   15087                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   15088                     return;
   15089                 }
   15090 
   15091                 // Not backing this app up any more; reset its OOM adjustment
   15092                 final ProcessRecord proc = mBackupTarget.app;
   15093                 updateOomAdjLocked(proc);
   15094 
   15095                 // If the app crashed during backup, 'thread' will be null here
   15096                 if (proc.thread != null) {
   15097                     try {
   15098                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   15099                                 compatibilityInfoForPackageLocked(appInfo));
   15100                     } catch (Exception e) {
   15101                         Slog.e(TAG, "Exception when unbinding backup agent:");
   15102                         e.printStackTrace();
   15103                     }
   15104                 }
   15105             } finally {
   15106                 mBackupTarget = null;
   15107                 mBackupAppName = null;
   15108             }
   15109         }
   15110     }
   15111     // =========================================================
   15112     // BROADCASTS
   15113     // =========================================================
   15114 
   15115     private final List getStickiesLocked(String action, IntentFilter filter,
   15116             List cur, int userId) {
   15117         final ContentResolver resolver = mContext.getContentResolver();
   15118         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   15119         if (stickies == null) {
   15120             return cur;
   15121         }
   15122         final ArrayList<Intent> list = stickies.get(action);
   15123         if (list == null) {
   15124             return cur;
   15125         }
   15126         int N = list.size();
   15127         for (int i=0; i<N; i++) {
   15128             Intent intent = list.get(i);
   15129             if (filter.match(resolver, intent, true, TAG) >= 0) {
   15130                 if (cur == null) {
   15131                     cur = new ArrayList<Intent>();
   15132                 }
   15133                 cur.add(intent);
   15134             }
   15135         }
   15136         return cur;
   15137     }
   15138 
   15139     boolean isPendingBroadcastProcessLocked(int pid) {
   15140         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   15141                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   15142     }
   15143 
   15144     void skipPendingBroadcastLocked(int pid) {
   15145             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   15146             for (BroadcastQueue queue : mBroadcastQueues) {
   15147                 queue.skipPendingBroadcastLocked(pid);
   15148             }
   15149     }
   15150 
   15151     // The app just attached; send any pending broadcasts that it should receive
   15152     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   15153         boolean didSomething = false;
   15154         for (BroadcastQueue queue : mBroadcastQueues) {
   15155             didSomething |= queue.sendPendingBroadcastsLocked(app);
   15156         }
   15157         return didSomething;
   15158     }
   15159 
   15160     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   15161             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   15162         enforceNotIsolatedCaller("registerReceiver");
   15163         int callingUid;
   15164         int callingPid;
   15165         synchronized(this) {
   15166             ProcessRecord callerApp = null;
   15167             if (caller != null) {
   15168                 callerApp = getRecordForAppLocked(caller);
   15169                 if (callerApp == null) {
   15170                     throw new SecurityException(
   15171                             "Unable to find app for caller " + caller
   15172                             + " (pid=" + Binder.getCallingPid()
   15173                             + ") when registering receiver " + receiver);
   15174                 }
   15175                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   15176                         !callerApp.pkgList.containsKey(callerPackage) &&
   15177                         !"android".equals(callerPackage)) {
   15178                     throw new SecurityException("Given caller package " + callerPackage
   15179                             + " is not running in process " + callerApp);
   15180                 }
   15181                 callingUid = callerApp.info.uid;
   15182                 callingPid = callerApp.pid;
   15183             } else {
   15184                 callerPackage = null;
   15185                 callingUid = Binder.getCallingUid();
   15186                 callingPid = Binder.getCallingPid();
   15187             }
   15188 
   15189             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   15190                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
   15191 
   15192             List allSticky = null;
   15193 
   15194             // Look for any matching sticky broadcasts...
   15195             Iterator actions = filter.actionsIterator();
   15196             if (actions != null) {
   15197                 while (actions.hasNext()) {
   15198                     String action = (String)actions.next();
   15199                     allSticky = getStickiesLocked(action, filter, allSticky,
   15200                             UserHandle.USER_ALL);
   15201                     allSticky = getStickiesLocked(action, filter, allSticky,
   15202                             UserHandle.getUserId(callingUid));
   15203                 }
   15204             } else {
   15205                 allSticky = getStickiesLocked(null, filter, allSticky,
   15206                         UserHandle.USER_ALL);
   15207                 allSticky = getStickiesLocked(null, filter, allSticky,
   15208                         UserHandle.getUserId(callingUid));
   15209             }
   15210 
   15211             // The first sticky in the list is returned directly back to
   15212             // the client.
   15213             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   15214 
   15215             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   15216                     + ": " + sticky);
   15217 
   15218             if (receiver == null) {
   15219                 return sticky;
   15220             }
   15221 
   15222             ReceiverList rl
   15223                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   15224             if (rl == null) {
   15225                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   15226                         userId, receiver);
   15227                 if (rl.app != null) {
   15228                     rl.app.receivers.add(rl);
   15229                 } else {
   15230                     try {
   15231                         receiver.asBinder().linkToDeath(rl, 0);
   15232                     } catch (RemoteException e) {
   15233                         return sticky;
   15234                     }
   15235                     rl.linkedToDeath = true;
   15236                 }
   15237                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   15238             } else if (rl.uid != callingUid) {
   15239                 throw new IllegalArgumentException(
   15240                         "Receiver requested to register for uid " + callingUid
   15241                         + " was previously registered for uid " + rl.uid);
   15242             } else if (rl.pid != callingPid) {
   15243                 throw new IllegalArgumentException(
   15244                         "Receiver requested to register for pid " + callingPid
   15245                         + " was previously registered for pid " + rl.pid);
   15246             } else if (rl.userId != userId) {
   15247                 throw new IllegalArgumentException(
   15248                         "Receiver requested to register for user " + userId
   15249                         + " was previously registered for user " + rl.userId);
   15250             }
   15251             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   15252                     permission, callingUid, userId);
   15253             rl.add(bf);
   15254             if (!bf.debugCheck()) {
   15255                 Slog.w(TAG, "==> For Dynamic broadast");
   15256             }
   15257             mReceiverResolver.addFilter(bf);
   15258 
   15259             // Enqueue broadcasts for all existing stickies that match
   15260             // this filter.
   15261             if (allSticky != null) {
   15262                 ArrayList receivers = new ArrayList();
   15263                 receivers.add(bf);
   15264 
   15265                 int N = allSticky.size();
   15266                 for (int i=0; i<N; i++) {
   15267                     Intent intent = (Intent)allSticky.get(i);
   15268                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   15269                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   15270                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   15271                             null, null, false, true, true, -1);
   15272                     queue.enqueueParallelBroadcastLocked(r);
   15273                     queue.scheduleBroadcastsLocked();
   15274                 }
   15275             }
   15276 
   15277             return sticky;
   15278         }
   15279     }
   15280 
   15281     public void unregisterReceiver(IIntentReceiver receiver) {
   15282         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   15283 
   15284         final long origId = Binder.clearCallingIdentity();
   15285         try {
   15286             boolean doTrim = false;
   15287 
   15288             synchronized(this) {
   15289                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   15290                 if (rl != null) {
   15291                     if (rl.curBroadcast != null) {
   15292                         BroadcastRecord r = rl.curBroadcast;
   15293                         final boolean doNext = finishReceiverLocked(
   15294                                 receiver.asBinder(), r.resultCode, r.resultData,
   15295                                 r.resultExtras, r.resultAbort);
   15296                         if (doNext) {
   15297                             doTrim = true;
   15298                             r.queue.processNextBroadcast(false);
   15299                         }
   15300                     }
   15301 
   15302                     if (rl.app != null) {
   15303                         rl.app.receivers.remove(rl);
   15304                     }
   15305                     removeReceiverLocked(rl);
   15306                     if (rl.linkedToDeath) {
   15307                         rl.linkedToDeath = false;
   15308                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   15309                     }
   15310                 }
   15311             }
   15312 
   15313             // If we actually concluded any broadcasts, we might now be able
   15314             // to trim the recipients' apps from our working set
   15315             if (doTrim) {
   15316                 trimApplications();
   15317                 return;
   15318             }
   15319 
   15320         } finally {
   15321             Binder.restoreCallingIdentity(origId);
   15322         }
   15323     }
   15324 
   15325     void removeReceiverLocked(ReceiverList rl) {
   15326         mRegisteredReceivers.remove(rl.receiver.asBinder());
   15327         int N = rl.size();
   15328         for (int i=0; i<N; i++) {
   15329             mReceiverResolver.removeFilter(rl.get(i));
   15330         }
   15331     }
   15332 
   15333     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   15334         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15335             ProcessRecord r = mLruProcesses.get(i);
   15336             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   15337                 try {
   15338                     r.thread.dispatchPackageBroadcast(cmd, packages);
   15339                 } catch (RemoteException ex) {
   15340                 }
   15341             }
   15342         }
   15343     }
   15344 
   15345     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   15346             int callingUid, int[] users) {
   15347         List<ResolveInfo> receivers = null;
   15348         try {
   15349             HashSet<ComponentName> singleUserReceivers = null;
   15350             boolean scannedFirstReceivers = false;
   15351             for (int user : users) {
   15352                 // Skip users that have Shell restrictions
   15353                 if (callingUid == Process.SHELL_UID
   15354                         && getUserManagerLocked().hasUserRestriction(
   15355                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
   15356                     continue;
   15357                 }
   15358                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   15359                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   15360                 if (user != 0 && newReceivers != null) {
   15361                     // If this is not the primary user, we need to check for
   15362                     // any receivers that should be filtered out.
   15363                     for (int i=0; i<newReceivers.size(); i++) {
   15364                         ResolveInfo ri = newReceivers.get(i);
   15365                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   15366                             newReceivers.remove(i);
   15367                             i--;
   15368                         }
   15369                     }
   15370                 }
   15371                 if (newReceivers != null && newReceivers.size() == 0) {
   15372                     newReceivers = null;
   15373                 }
   15374                 if (receivers == null) {
   15375                     receivers = newReceivers;
   15376                 } else if (newReceivers != null) {
   15377                     // We need to concatenate the additional receivers
   15378                     // found with what we have do far.  This would be easy,
   15379                     // but we also need to de-dup any receivers that are
   15380                     // singleUser.
   15381                     if (!scannedFirstReceivers) {
   15382                         // Collect any single user receivers we had already retrieved.
   15383                         scannedFirstReceivers = true;
   15384                         for (int i=0; i<receivers.size(); i++) {
   15385                             ResolveInfo ri = receivers.get(i);
   15386                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15387                                 ComponentName cn = new ComponentName(
   15388                                         ri.activityInfo.packageName, ri.activityInfo.name);
   15389                                 if (singleUserReceivers == null) {
   15390                                     singleUserReceivers = new HashSet<ComponentName>();
   15391                                 }
   15392                                 singleUserReceivers.add(cn);
   15393                             }
   15394                         }
   15395                     }
   15396                     // Add the new results to the existing results, tracking
   15397                     // and de-dupping single user receivers.
   15398                     for (int i=0; i<newReceivers.size(); i++) {
   15399                         ResolveInfo ri = newReceivers.get(i);
   15400                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   15401                             ComponentName cn = new ComponentName(
   15402                                     ri.activityInfo.packageName, ri.activityInfo.name);
   15403                             if (singleUserReceivers == null) {
   15404                                 singleUserReceivers = new HashSet<ComponentName>();
   15405                             }
   15406                             if (!singleUserReceivers.contains(cn)) {
   15407                                 singleUserReceivers.add(cn);
   15408                                 receivers.add(ri);
   15409                             }
   15410                         } else {
   15411                             receivers.add(ri);
   15412                         }
   15413                     }
   15414                 }
   15415             }
   15416         } catch (RemoteException ex) {
   15417             // pm is in same process, this will never happen.
   15418         }
   15419         return receivers;
   15420     }
   15421 
   15422     private final int broadcastIntentLocked(ProcessRecord callerApp,
   15423             String callerPackage, Intent intent, String resolvedType,
   15424             IIntentReceiver resultTo, int resultCode, String resultData,
   15425             Bundle map, String requiredPermission, int appOp,
   15426             boolean ordered, boolean sticky, int callingPid, int callingUid,
   15427             int userId) {
   15428         intent = new Intent(intent);
   15429 
   15430         // By default broadcasts do not go to stopped apps.
   15431         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   15432 
   15433         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   15434             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   15435             + " ordered=" + ordered + " userid=" + userId);
   15436         if ((resultTo != null) && !ordered) {
   15437             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   15438         }
   15439 
   15440         userId = handleIncomingUser(callingPid, callingUid, userId,
   15441                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
   15442 
   15443         // Make sure that the user who is receiving this broadcast is started.
   15444         // If not, we will just skip it.
   15445 
   15446         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   15447             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   15448                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   15449                 Slog.w(TAG, "Skipping broadcast of " + intent
   15450                         + ": user " + userId + " is stopped");
   15451                 return ActivityManager.BROADCAST_SUCCESS;
   15452             }
   15453         }
   15454 
   15455         /*
   15456          * Prevent non-system code (defined here to be non-persistent
   15457          * processes) from sending protected broadcasts.
   15458          */
   15459         int callingAppId = UserHandle.getAppId(callingUid);
   15460         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   15461             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
   15462             || callingAppId == Process.NFC_UID || callingUid == 0) {
   15463             // Always okay.
   15464         } else if (callerApp == null || !callerApp.persistent) {
   15465             try {
   15466                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   15467                         intent.getAction())) {
   15468                     String msg = "Permission Denial: not allowed to send broadcast "
   15469                             + intent.getAction() + " from pid="
   15470                             + callingPid + ", uid=" + callingUid;
   15471                     Slog.w(TAG, msg);
   15472                     throw new SecurityException(msg);
   15473                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   15474                     // Special case for compatibility: we don't want apps to send this,
   15475                     // but historically it has not been protected and apps may be using it
   15476                     // to poke their own app widget.  So, instead of making it protected,
   15477                     // just limit it to the caller.
   15478                     if (callerApp == null) {
   15479                         String msg = "Permission Denial: not allowed to send broadcast "
   15480                                 + intent.getAction() + " from unknown caller.";
   15481                         Slog.w(TAG, msg);
   15482                         throw new SecurityException(msg);
   15483                     } else if (intent.getComponent() != null) {
   15484                         // They are good enough to send to an explicit component...  verify
   15485                         // it is being sent to the calling app.
   15486                         if (!intent.getComponent().getPackageName().equals(
   15487                                 callerApp.info.packageName)) {
   15488                             String msg = "Permission Denial: not allowed to send broadcast "
   15489                                     + intent.getAction() + " to "
   15490                                     + intent.getComponent().getPackageName() + " from "
   15491                                     + callerApp.info.packageName;
   15492                             Slog.w(TAG, msg);
   15493                             throw new SecurityException(msg);
   15494                         }
   15495                     } else {
   15496                         // Limit broadcast to their own package.
   15497                         intent.setPackage(callerApp.info.packageName);
   15498                     }
   15499                 }
   15500             } catch (RemoteException e) {
   15501                 Slog.w(TAG, "Remote exception", e);
   15502                 return ActivityManager.BROADCAST_SUCCESS;
   15503             }
   15504         }
   15505 
   15506         // Handle special intents: if this broadcast is from the package
   15507         // manager about a package being removed, we need to remove all of
   15508         // its activities from the history stack.
   15509         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   15510                 intent.getAction());
   15511         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   15512                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   15513                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   15514                 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
   15515                 || uidRemoved) {
   15516             if (checkComponentPermission(
   15517                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   15518                     callingPid, callingUid, -1, true)
   15519                     == PackageManager.PERMISSION_GRANTED) {
   15520                 if (uidRemoved) {
   15521                     final Bundle intentExtras = intent.getExtras();
   15522                     final int uid = intentExtras != null
   15523                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   15524                     if (uid >= 0) {
   15525                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   15526                         synchronized (bs) {
   15527                             bs.removeUidStatsLocked(uid);
   15528                         }
   15529                         mAppOpsService.uidRemoved(uid);
   15530                     }
   15531                 } else {
   15532                     // If resources are unavailable just force stop all
   15533                     // those packages and flush the attribute cache as well.
   15534                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   15535                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   15536                         if (list != null && (list.length > 0)) {
   15537                             for (String pkg : list) {
   15538                                 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
   15539                                         "storage unmount");
   15540                             }
   15541                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15542                             sendPackageBroadcastLocked(
   15543                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   15544                         }
   15545                     } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
   15546                             intent.getAction())) {
   15547                         cleanupRecentTasksLocked(UserHandle.USER_ALL);
   15548                     } else {
   15549                         Uri data = intent.getData();
   15550                         String ssp;
   15551                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   15552                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
   15553                                     intent.getAction());
   15554                             boolean fullUninstall = removed &&
   15555                                     !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   15556                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   15557                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
   15558                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
   15559                                         false, fullUninstall, userId,
   15560                                         removed ? "pkg removed" : "pkg changed");
   15561                             }
   15562                             if (removed) {
   15563                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   15564                                         new String[] {ssp}, userId);
   15565                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
   15566                                     mAppOpsService.packageRemoved(
   15567                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   15568 
   15569                                     // Remove all permissions granted from/to this package
   15570                                     removeUriPermissionsForPackageLocked(ssp, userId, true);
   15571                                 }
   15572                             }
   15573                         }
   15574                     }
   15575                 }
   15576             } else {
   15577                 String msg = "Permission Denial: " + intent.getAction()
   15578                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   15579                         + ", uid=" + callingUid + ")"
   15580                         + " requires "
   15581                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   15582                 Slog.w(TAG, msg);
   15583                 throw new SecurityException(msg);
   15584             }
   15585 
   15586         // Special case for adding a package: by default turn on compatibility
   15587         // mode.
   15588         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   15589             Uri data = intent.getData();
   15590             String ssp;
   15591             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   15592                 mCompatModePackages.handlePackageAddedLocked(ssp,
   15593                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   15594             }
   15595         }
   15596 
   15597         /*
   15598          * If this is the time zone changed action, queue up a message that will reset the timezone
   15599          * of all currently running processes. This message will get queued up before the broadcast
   15600          * happens.
   15601          */
   15602         if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   15603             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   15604         }
   15605 
   15606         /*
   15607          * If the user set the time, let all running processes know.
   15608          */
   15609         if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
   15610             final int is24Hour = intent.getBooleanExtra(
   15611                     Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
   15612             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
   15613             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15614             synchronized (stats) {
   15615                 stats.noteCurrentTimeChangedLocked();
   15616             }
   15617         }
   15618 
   15619         if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   15620             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   15621         }
   15622 
   15623         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   15624             ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
   15625             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   15626         }
   15627 
   15628         // Add to the sticky list if requested.
   15629         if (sticky) {
   15630             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   15631                     callingPid, callingUid)
   15632                     != PackageManager.PERMISSION_GRANTED) {
   15633                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   15634                         + callingPid + ", uid=" + callingUid
   15635                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   15636                 Slog.w(TAG, msg);
   15637                 throw new SecurityException(msg);
   15638             }
   15639             if (requiredPermission != null) {
   15640                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   15641                         + " and enforce permission " + requiredPermission);
   15642                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   15643             }
   15644             if (intent.getComponent() != null) {
   15645                 throw new SecurityException(
   15646                         "Sticky broadcasts can't target a specific component");
   15647             }
   15648             // We use userId directly here, since the "all" target is maintained
   15649             // as a separate set of sticky broadcasts.
   15650             if (userId != UserHandle.USER_ALL) {
   15651                 // But first, if this is not a broadcast to all users, then
   15652                 // make sure it doesn't conflict with an existing broadcast to
   15653                 // all users.
   15654                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   15655                         UserHandle.USER_ALL);
   15656                 if (stickies != null) {
   15657                     ArrayList<Intent> list = stickies.get(intent.getAction());
   15658                     if (list != null) {
   15659                         int N = list.size();
   15660                         int i;
   15661                         for (i=0; i<N; i++) {
   15662                             if (intent.filterEquals(list.get(i))) {
   15663                                 throw new IllegalArgumentException(
   15664                                         "Sticky broadcast " + intent + " for user "
   15665                                         + userId + " conflicts with existing global broadcast");
   15666                             }
   15667                         }
   15668                     }
   15669                 }
   15670             }
   15671             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   15672             if (stickies == null) {
   15673                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   15674                 mStickyBroadcasts.put(userId, stickies);
   15675             }
   15676             ArrayList<Intent> list = stickies.get(intent.getAction());
   15677             if (list == null) {
   15678                 list = new ArrayList<Intent>();
   15679                 stickies.put(intent.getAction(), list);
   15680             }
   15681             int N = list.size();
   15682             int i;
   15683             for (i=0; i<N; i++) {
   15684                 if (intent.filterEquals(list.get(i))) {
   15685                     // This sticky already exists, replace it.
   15686                     list.set(i, new Intent(intent));
   15687                     break;
   15688                 }
   15689             }
   15690             if (i >= N) {
   15691                 list.add(new Intent(intent));
   15692             }
   15693         }
   15694 
   15695         int[] users;
   15696         if (userId == UserHandle.USER_ALL) {
   15697             // Caller wants broadcast to go to all started users.
   15698             users = mStartedUserArray;
   15699         } else {
   15700             // Caller wants broadcast to go to one specific user.
   15701             users = new int[] {userId};
   15702         }
   15703 
   15704         // Figure out who all will receive this broadcast.
   15705         List receivers = null;
   15706         List<BroadcastFilter> registeredReceivers = null;
   15707         // Need to resolve the intent to interested receivers...
   15708         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   15709                  == 0) {
   15710             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
   15711         }
   15712         if (intent.getComponent() == null) {
   15713             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
   15714                 // Query one target user at a time, excluding shell-restricted users
   15715                 UserManagerService ums = getUserManagerLocked();
   15716                 for (int i = 0; i < users.length; i++) {
   15717                     if (ums.hasUserRestriction(
   15718                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
   15719                         continue;
   15720                     }
   15721                     List<BroadcastFilter> registeredReceiversForUser =
   15722                             mReceiverResolver.queryIntent(intent,
   15723                                     resolvedType, false, users[i]);
   15724                     if (registeredReceivers == null) {
   15725                         registeredReceivers = registeredReceiversForUser;
   15726                     } else if (registeredReceiversForUser != null) {
   15727                         registeredReceivers.addAll(registeredReceiversForUser);
   15728                     }
   15729                 }
   15730             } else {
   15731                 registeredReceivers = mReceiverResolver.queryIntent(intent,
   15732                         resolvedType, false, userId);
   15733             }
   15734         }
   15735 
   15736         final boolean replacePending =
   15737                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   15738 
   15739         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   15740                 + " replacePending=" + replacePending);
   15741 
   15742         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   15743         if (!ordered && NR > 0) {
   15744             // If we are not serializing this broadcast, then send the
   15745             // registered receivers separately so they don't wait for the
   15746             // components to be launched.
   15747             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   15748             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   15749                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   15750                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   15751                     ordered, sticky, false, userId);
   15752             if (DEBUG_BROADCAST) Slog.v(
   15753                     TAG, "Enqueueing parallel broadcast " + r);
   15754             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   15755             if (!replaced) {
   15756                 queue.enqueueParallelBroadcastLocked(r);
   15757                 queue.scheduleBroadcastsLocked();
   15758             }
   15759             registeredReceivers = null;
   15760             NR = 0;
   15761         }
   15762 
   15763         // Merge into one list.
   15764         int ir = 0;
   15765         if (receivers != null) {
   15766             // A special case for PACKAGE_ADDED: do not allow the package
   15767             // being added to see this broadcast.  This prevents them from
   15768             // using this as a back door to get run as soon as they are
   15769             // installed.  Maybe in the future we want to have a special install
   15770             // broadcast or such for apps, but we'd like to deliberately make
   15771             // this decision.
   15772             String skipPackages[] = null;
   15773             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   15774                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   15775                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   15776                 Uri data = intent.getData();
   15777                 if (data != null) {
   15778                     String pkgName = data.getSchemeSpecificPart();
   15779                     if (pkgName != null) {
   15780                         skipPackages = new String[] { pkgName };
   15781                     }
   15782                 }
   15783             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   15784                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   15785             }
   15786             if (skipPackages != null && (skipPackages.length > 0)) {
   15787                 for (String skipPackage : skipPackages) {
   15788                     if (skipPackage != null) {
   15789                         int NT = receivers.size();
   15790                         for (int it=0; it<NT; it++) {
   15791                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   15792                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   15793                                 receivers.remove(it);
   15794                                 it--;
   15795                                 NT--;
   15796                             }
   15797                         }
   15798                     }
   15799                 }
   15800             }
   15801 
   15802             int NT = receivers != null ? receivers.size() : 0;
   15803             int it = 0;
   15804             ResolveInfo curt = null;
   15805             BroadcastFilter curr = null;
   15806             while (it < NT && ir < NR) {
   15807                 if (curt == null) {
   15808                     curt = (ResolveInfo)receivers.get(it);
   15809                 }
   15810                 if (curr == null) {
   15811                     curr = registeredReceivers.get(ir);
   15812                 }
   15813                 if (curr.getPriority() >= curt.priority) {
   15814                     // Insert this broadcast record into the final list.
   15815                     receivers.add(it, curr);
   15816                     ir++;
   15817                     curr = null;
   15818                     it++;
   15819                     NT++;
   15820                 } else {
   15821                     // Skip to the next ResolveInfo in the final list.
   15822                     it++;
   15823                     curt = null;
   15824                 }
   15825             }
   15826         }
   15827         while (ir < NR) {
   15828             if (receivers == null) {
   15829                 receivers = new ArrayList();
   15830             }
   15831             receivers.add(registeredReceivers.get(ir));
   15832             ir++;
   15833         }
   15834 
   15835         if ((receivers != null && receivers.size() > 0)
   15836                 || resultTo != null) {
   15837             BroadcastQueue queue = broadcastQueueForIntent(intent);
   15838             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   15839                     callerPackage, callingPid, callingUid, resolvedType,
   15840                     requiredPermission, appOp, receivers, resultTo, resultCode,
   15841                     resultData, map, ordered, sticky, false, userId);
   15842             if (DEBUG_BROADCAST) Slog.v(
   15843                     TAG, "Enqueueing ordered broadcast " + r
   15844                     + ": prev had " + queue.mOrderedBroadcasts.size());
   15845             if (DEBUG_BROADCAST) {
   15846                 int seq = r.intent.getIntExtra("seq", -1);
   15847                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   15848             }
   15849             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   15850             if (!replaced) {
   15851                 queue.enqueueOrderedBroadcastLocked(r);
   15852                 queue.scheduleBroadcastsLocked();
   15853             }
   15854         }
   15855 
   15856         return ActivityManager.BROADCAST_SUCCESS;
   15857     }
   15858 
   15859     final Intent verifyBroadcastLocked(Intent intent) {
   15860         // Refuse possible leaked file descriptors
   15861         if (intent != null && intent.hasFileDescriptors() == true) {
   15862             throw new IllegalArgumentException("File descriptors passed in Intent");
   15863         }
   15864 
   15865         int flags = intent.getFlags();
   15866 
   15867         if (!mProcessesReady) {
   15868             // if the caller really truly claims to know what they're doing, go
   15869             // ahead and allow the broadcast without launching any receivers
   15870             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   15871                 intent = new Intent(intent);
   15872                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   15873             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   15874                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   15875                         + " before boot completion");
   15876                 throw new IllegalStateException("Cannot broadcast before boot completed");
   15877             }
   15878         }
   15879 
   15880         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   15881             throw new IllegalArgumentException(
   15882                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   15883         }
   15884 
   15885         return intent;
   15886     }
   15887 
   15888     public final int broadcastIntent(IApplicationThread caller,
   15889             Intent intent, String resolvedType, IIntentReceiver resultTo,
   15890             int resultCode, String resultData, Bundle map,
   15891             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   15892         enforceNotIsolatedCaller("broadcastIntent");
   15893         synchronized(this) {
   15894             intent = verifyBroadcastLocked(intent);
   15895 
   15896             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   15897             final int callingPid = Binder.getCallingPid();
   15898             final int callingUid = Binder.getCallingUid();
   15899             final long origId = Binder.clearCallingIdentity();
   15900             int res = broadcastIntentLocked(callerApp,
   15901                     callerApp != null ? callerApp.info.packageName : null,
   15902                     intent, resolvedType, resultTo,
   15903                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   15904                     callingPid, callingUid, userId);
   15905             Binder.restoreCallingIdentity(origId);
   15906             return res;
   15907         }
   15908     }
   15909 
   15910     int broadcastIntentInPackage(String packageName, int uid,
   15911             Intent intent, String resolvedType, IIntentReceiver resultTo,
   15912             int resultCode, String resultData, Bundle map,
   15913             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   15914         synchronized(this) {
   15915             intent = verifyBroadcastLocked(intent);
   15916 
   15917             final long origId = Binder.clearCallingIdentity();
   15918             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   15919                     resultTo, resultCode, resultData, map, requiredPermission,
   15920                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   15921             Binder.restoreCallingIdentity(origId);
   15922             return res;
   15923         }
   15924     }
   15925 
   15926     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   15927         // Refuse possible leaked file descriptors
   15928         if (intent != null && intent.hasFileDescriptors() == true) {
   15929             throw new IllegalArgumentException("File descriptors passed in Intent");
   15930         }
   15931 
   15932         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   15933                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
   15934 
   15935         synchronized(this) {
   15936             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   15937                     != PackageManager.PERMISSION_GRANTED) {
   15938                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   15939                         + Binder.getCallingPid()
   15940                         + ", uid=" + Binder.getCallingUid()
   15941                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   15942                 Slog.w(TAG, msg);
   15943                 throw new SecurityException(msg);
   15944             }
   15945             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   15946             if (stickies != null) {
   15947                 ArrayList<Intent> list = stickies.get(intent.getAction());
   15948                 if (list != null) {
   15949                     int N = list.size();
   15950                     int i;
   15951                     for (i=0; i<N; i++) {
   15952                         if (intent.filterEquals(list.get(i))) {
   15953                             list.remove(i);
   15954                             break;
   15955                         }
   15956                     }
   15957                     if (list.size() <= 0) {
   15958                         stickies.remove(intent.getAction());
   15959                     }
   15960                 }
   15961                 if (stickies.size() <= 0) {
   15962                     mStickyBroadcasts.remove(userId);
   15963                 }
   15964             }
   15965         }
   15966     }
   15967 
   15968     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   15969             String resultData, Bundle resultExtras, boolean resultAbort) {
   15970         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   15971         if (r == null) {
   15972             Slog.w(TAG, "finishReceiver called but not found on queue");
   15973             return false;
   15974         }
   15975 
   15976         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   15977     }
   15978 
   15979     void backgroundServicesFinishedLocked(int userId) {
   15980         for (BroadcastQueue queue : mBroadcastQueues) {
   15981             queue.backgroundServicesFinishedLocked(userId);
   15982         }
   15983     }
   15984 
   15985     public void finishReceiver(IBinder who, int resultCode, String resultData,
   15986             Bundle resultExtras, boolean resultAbort) {
   15987         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   15988 
   15989         // Refuse possible leaked file descriptors
   15990         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   15991             throw new IllegalArgumentException("File descriptors passed in Bundle");
   15992         }
   15993 
   15994         final long origId = Binder.clearCallingIdentity();
   15995         try {
   15996             boolean doNext = false;
   15997             BroadcastRecord r;
   15998 
   15999             synchronized(this) {
   16000                 r = broadcastRecordForReceiverLocked(who);
   16001                 if (r != null) {
   16002                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   16003                         resultData, resultExtras, resultAbort, true);
   16004                 }
   16005             }
   16006 
   16007             if (doNext) {
   16008                 r.queue.processNextBroadcast(false);
   16009             }
   16010             trimApplications();
   16011         } finally {
   16012             Binder.restoreCallingIdentity(origId);
   16013         }
   16014     }
   16015 
   16016     // =========================================================
   16017     // INSTRUMENTATION
   16018     // =========================================================
   16019 
   16020     public boolean startInstrumentation(ComponentName className,
   16021             String profileFile, int flags, Bundle arguments,
   16022             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   16023             int userId, String abiOverride) {
   16024         enforceNotIsolatedCaller("startInstrumentation");
   16025         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   16026                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
   16027         // Refuse possible leaked file descriptors
   16028         if (arguments != null && arguments.hasFileDescriptors()) {
   16029             throw new IllegalArgumentException("File descriptors passed in Bundle");
   16030         }
   16031 
   16032         synchronized(this) {
   16033             InstrumentationInfo ii = null;
   16034             ApplicationInfo ai = null;
   16035             try {
   16036                 ii = mContext.getPackageManager().getInstrumentationInfo(
   16037                     className, STOCK_PM_FLAGS);
   16038                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   16039                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   16040             } catch (PackageManager.NameNotFoundException e) {
   16041             } catch (RemoteException e) {
   16042             }
   16043             if (ii == null) {
   16044                 reportStartInstrumentationFailure(watcher, className,
   16045                         "Unable to find instrumentation info for: " + className);
   16046                 return false;
   16047             }
   16048             if (ai == null) {
   16049                 reportStartInstrumentationFailure(watcher, className,
   16050                         "Unable to find instrumentation target package: " + ii.targetPackage);
   16051                 return false;
   16052             }
   16053 
   16054             int match = mContext.getPackageManager().checkSignatures(
   16055                     ii.targetPackage, ii.packageName);
   16056             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   16057                 String msg = "Permission Denial: starting instrumentation "
   16058                         + className + " from pid="
   16059                         + Binder.getCallingPid()
   16060                         + ", uid=" + Binder.getCallingPid()
   16061                         + " not allowed because package " + ii.packageName
   16062                         + " does not have a signature matching the target "
   16063                         + ii.targetPackage;
   16064                 reportStartInstrumentationFailure(watcher, className, msg);
   16065                 throw new SecurityException(msg);
   16066             }
   16067 
   16068             final long origId = Binder.clearCallingIdentity();
   16069             // Instrumentation can kill and relaunch even persistent processes
   16070             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   16071                     "start instr");
   16072             ProcessRecord app = addAppLocked(ai, false, abiOverride);
   16073             app.instrumentationClass = className;
   16074             app.instrumentationInfo = ai;
   16075             app.instrumentationProfileFile = profileFile;
   16076             app.instrumentationArguments = arguments;
   16077             app.instrumentationWatcher = watcher;
   16078             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   16079             app.instrumentationResultClass = className;
   16080             Binder.restoreCallingIdentity(origId);
   16081         }
   16082 
   16083         return true;
   16084     }
   16085 
   16086     /**
   16087      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   16088      * error to the logs, but if somebody is watching, send the report there too.  This enables
   16089      * the "am" command to report errors with more information.
   16090      *
   16091      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   16092      * @param cn The component name of the instrumentation.
   16093      * @param report The error report.
   16094      */
   16095     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   16096             ComponentName cn, String report) {
   16097         Slog.w(TAG, report);
   16098         try {
   16099             if (watcher != null) {
   16100                 Bundle results = new Bundle();
   16101                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   16102                 results.putString("Error", report);
   16103                 watcher.instrumentationStatus(cn, -1, results);
   16104             }
   16105         } catch (RemoteException e) {
   16106             Slog.w(TAG, e);
   16107         }
   16108     }
   16109 
   16110     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   16111         if (app.instrumentationWatcher != null) {
   16112             try {
   16113                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   16114                 app.instrumentationWatcher.instrumentationFinished(
   16115                     app.instrumentationClass,
   16116                     resultCode,
   16117                     results);
   16118             } catch (RemoteException e) {
   16119             }
   16120         }
   16121         if (app.instrumentationUiAutomationConnection != null) {
   16122             try {
   16123                 app.instrumentationUiAutomationConnection.shutdown();
   16124             } catch (RemoteException re) {
   16125                 /* ignore */
   16126             }
   16127             // Only a UiAutomation can set this flag and now that
   16128             // it is finished we make sure it is reset to its default.
   16129             mUserIsMonkey = false;
   16130         }
   16131         app.instrumentationWatcher = null;
   16132         app.instrumentationUiAutomationConnection = null;
   16133         app.instrumentationClass = null;
   16134         app.instrumentationInfo = null;
   16135         app.instrumentationProfileFile = null;
   16136         app.instrumentationArguments = null;
   16137 
   16138         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   16139                 "finished inst");
   16140     }
   16141 
   16142     public void finishInstrumentation(IApplicationThread target,
   16143             int resultCode, Bundle results) {
   16144         int userId = UserHandle.getCallingUserId();
   16145         // Refuse possible leaked file descriptors
   16146         if (results != null && results.hasFileDescriptors()) {
   16147             throw new IllegalArgumentException("File descriptors passed in Intent");
   16148         }
   16149 
   16150         synchronized(this) {
   16151             ProcessRecord app = getRecordForAppLocked(target);
   16152             if (app == null) {
   16153                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   16154                 return;
   16155             }
   16156             final long origId = Binder.clearCallingIdentity();
   16157             finishInstrumentationLocked(app, resultCode, results);
   16158             Binder.restoreCallingIdentity(origId);
   16159         }
   16160     }
   16161 
   16162     // =========================================================
   16163     // CONFIGURATION
   16164     // =========================================================
   16165 
   16166     public ConfigurationInfo getDeviceConfigurationInfo() {
   16167         ConfigurationInfo config = new ConfigurationInfo();
   16168         synchronized (this) {
   16169             config.reqTouchScreen = mConfiguration.touchscreen;
   16170             config.reqKeyboardType = mConfiguration.keyboard;
   16171             config.reqNavigation = mConfiguration.navigation;
   16172             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   16173                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   16174                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   16175             }
   16176             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   16177                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   16178                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   16179             }
   16180             config.reqGlEsVersion = GL_ES_VERSION;
   16181         }
   16182         return config;
   16183     }
   16184 
   16185     ActivityStack getFocusedStack() {
   16186         return mStackSupervisor.getFocusedStack();
   16187     }
   16188 
   16189     public Configuration getConfiguration() {
   16190         Configuration ci;
   16191         synchronized(this) {
   16192             ci = new Configuration(mConfiguration);
   16193         }
   16194         return ci;
   16195     }
   16196 
   16197     public void updatePersistentConfiguration(Configuration values) {
   16198         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16199                 "updateConfiguration()");
   16200         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   16201                 "updateConfiguration()");
   16202         if (values == null) {
   16203             throw new NullPointerException("Configuration must not be null");
   16204         }
   16205 
   16206         synchronized(this) {
   16207             final long origId = Binder.clearCallingIdentity();
   16208             updateConfigurationLocked(values, null, true, false);
   16209             Binder.restoreCallingIdentity(origId);
   16210         }
   16211     }
   16212 
   16213     public void updateConfiguration(Configuration values) {
   16214         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   16215                 "updateConfiguration()");
   16216 
   16217         synchronized(this) {
   16218             if (values == null && mWindowManager != null) {
   16219                 // sentinel: fetch the current configuration from the window manager
   16220                 values = mWindowManager.computeNewConfiguration();
   16221             }
   16222 
   16223             if (mWindowManager != null) {
   16224                 mProcessList.applyDisplaySize(mWindowManager);
   16225             }
   16226 
   16227             final long origId = Binder.clearCallingIdentity();
   16228             if (values != null) {
   16229                 Settings.System.clearConfiguration(values);
   16230             }
   16231             updateConfigurationLocked(values, null, false, false);
   16232             Binder.restoreCallingIdentity(origId);
   16233         }
   16234     }
   16235 
   16236     /**
   16237      * Do either or both things: (1) change the current configuration, and (2)
   16238      * make sure the given activity is running with the (now) current
   16239      * configuration.  Returns true if the activity has been left running, or
   16240      * false if <var>starting</var> is being destroyed to match the new
   16241      * configuration.
   16242      * @param persistent TODO
   16243      */
   16244     boolean updateConfigurationLocked(Configuration values,
   16245             ActivityRecord starting, boolean persistent, boolean initLocale) {
   16246         int changes = 0;
   16247 
   16248         if (values != null) {
   16249             Configuration newConfig = new Configuration(mConfiguration);
   16250             changes = newConfig.updateFrom(values);
   16251             if (changes != 0) {
   16252                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   16253                     Slog.i(TAG, "Updating configuration to: " + values);
   16254                 }
   16255 
   16256                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   16257 
   16258                 if (values.locale != null && !initLocale) {
   16259                     saveLocaleLocked(values.locale,
   16260                                      !values.locale.equals(mConfiguration.locale),
   16261                                      values.userSetLocale);
   16262                 }
   16263 
   16264                 mConfigurationSeq++;
   16265                 if (mConfigurationSeq <= 0) {
   16266                     mConfigurationSeq = 1;
   16267                 }
   16268                 newConfig.seq = mConfigurationSeq;
   16269                 mConfiguration = newConfig;
   16270                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   16271                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
   16272                 //mUsageStatsService.noteStartConfig(newConfig);
   16273 
   16274                 final Configuration configCopy = new Configuration(mConfiguration);
   16275 
   16276                 // TODO: If our config changes, should we auto dismiss any currently
   16277                 // showing dialogs?
   16278                 mShowDialogs = shouldShowDialogs(newConfig);
   16279 
   16280                 AttributeCache ac = AttributeCache.instance();
   16281                 if (ac != null) {
   16282                     ac.updateConfiguration(configCopy);
   16283                 }
   16284 
   16285                 // Make sure all resources in our process are updated
   16286                 // right now, so that anyone who is going to retrieve
   16287                 // resource values after we return will be sure to get
   16288                 // the new ones.  This is especially important during
   16289                 // boot, where the first config change needs to guarantee
   16290                 // all resources have that config before following boot
   16291                 // code is executed.
   16292                 mSystemThread.applyConfigurationToResources(configCopy);
   16293 
   16294                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   16295                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   16296                     msg.obj = new Configuration(configCopy);
   16297                     mHandler.sendMessage(msg);
   16298                 }
   16299 
   16300                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   16301                     ProcessRecord app = mLruProcesses.get(i);
   16302                     try {
   16303                         if (app.thread != null) {
   16304                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   16305                                     + app.processName + " new config " + mConfiguration);
   16306                             app.thread.scheduleConfigurationChanged(configCopy);
   16307                         }
   16308                     } catch (Exception e) {
   16309                     }
   16310                 }
   16311                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   16312                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16313                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   16314                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16315                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   16316                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   16317                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   16318                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   16319                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   16320                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   16321                     broadcastIntentLocked(null, null, intent,
   16322                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16323                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16324                 }
   16325             }
   16326         }
   16327 
   16328         boolean kept = true;
   16329         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   16330         // mainStack is null during startup.
   16331         if (mainStack != null) {
   16332             if (changes != 0 && starting == null) {
   16333                 // If the configuration changed, and the caller is not already
   16334                 // in the process of starting an activity, then find the top
   16335                 // activity to check if its configuration needs to change.
   16336                 starting = mainStack.topRunningActivityLocked(null);
   16337             }
   16338 
   16339             if (starting != null) {
   16340                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   16341                 // And we need to make sure at this point that all other activities
   16342                 // are made visible with the correct configuration.
   16343                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   16344             }
   16345         }
   16346 
   16347         if (values != null && mWindowManager != null) {
   16348             mWindowManager.setNewConfiguration(mConfiguration);
   16349         }
   16350 
   16351         return kept;
   16352     }
   16353 
   16354     /**
   16355      * Decide based on the configuration whether we should shouw the ANR,
   16356      * crash, etc dialogs.  The idea is that if there is no affordnace to
   16357      * press the on-screen buttons, we shouldn't show the dialog.
   16358      *
   16359      * A thought: SystemUI might also want to get told about this, the Power
   16360      * dialog / global actions also might want different behaviors.
   16361      */
   16362     private static final boolean shouldShowDialogs(Configuration config) {
   16363         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   16364                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   16365     }
   16366 
   16367     /**
   16368      * Save the locale.  You must be inside a synchronized (this) block.
   16369      */
   16370     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   16371         if(isDiff) {
   16372             SystemProperties.set("user.language", l.getLanguage());
   16373             SystemProperties.set("user.region", l.getCountry());
   16374         }
   16375 
   16376         if(isPersist) {
   16377             SystemProperties.set("persist.sys.language", l.getLanguage());
   16378             SystemProperties.set("persist.sys.country", l.getCountry());
   16379             SystemProperties.set("persist.sys.localevar", l.getVariant());
   16380 
   16381             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
   16382         }
   16383     }
   16384 
   16385     @Override
   16386     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
   16387         synchronized (this) {
   16388             ActivityRecord srec = ActivityRecord.forToken(token);
   16389             if (srec.task != null && srec.task.stack != null) {
   16390                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
   16391             }
   16392         }
   16393         return false;
   16394     }
   16395 
   16396     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   16397             Intent resultData) {
   16398 
   16399         synchronized (this) {
   16400             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   16401             if (stack != null) {
   16402                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   16403             }
   16404             return false;
   16405         }
   16406     }
   16407 
   16408     public int getLaunchedFromUid(IBinder activityToken) {
   16409         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16410         if (srec == null) {
   16411             return -1;
   16412         }
   16413         return srec.launchedFromUid;
   16414     }
   16415 
   16416     public String getLaunchedFromPackage(IBinder activityToken) {
   16417         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   16418         if (srec == null) {
   16419             return null;
   16420         }
   16421         return srec.launchedFromPackage;
   16422     }
   16423 
   16424     // =========================================================
   16425     // LIFETIME MANAGEMENT
   16426     // =========================================================
   16427 
   16428     // Returns which broadcast queue the app is the current [or imminent] receiver
   16429     // on, or 'null' if the app is not an active broadcast recipient.
   16430     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   16431         BroadcastRecord r = app.curReceiver;
   16432         if (r != null) {
   16433             return r.queue;
   16434         }
   16435 
   16436         // It's not the current receiver, but it might be starting up to become one
   16437         synchronized (this) {
   16438             for (BroadcastQueue queue : mBroadcastQueues) {
   16439                 r = queue.mPendingBroadcast;
   16440                 if (r != null && r.curApp == app) {
   16441                     // found it; report which queue it's in
   16442                     return queue;
   16443                 }
   16444             }
   16445         }
   16446 
   16447         return null;
   16448     }
   16449 
   16450     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   16451             boolean doingAll, long now) {
   16452         if (mAdjSeq == app.adjSeq) {
   16453             // This adjustment has already been computed.
   16454             return app.curRawAdj;
   16455         }
   16456 
   16457         if (app.thread == null) {
   16458             app.adjSeq = mAdjSeq;
   16459             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16460             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16461             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   16462         }
   16463 
   16464         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   16465         app.adjSource = null;
   16466         app.adjTarget = null;
   16467         app.empty = false;
   16468         app.cached = false;
   16469 
   16470         final int activitiesSize = app.activities.size();
   16471 
   16472         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   16473             // The max adjustment doesn't allow this app to be anything
   16474             // below foreground, so it is not worth doing work for it.
   16475             app.adjType = "fixed";
   16476             app.adjSeq = mAdjSeq;
   16477             app.curRawAdj = app.maxAdj;
   16478             app.foregroundActivities = false;
   16479             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   16480             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   16481             // System processes can do UI, and when they do we want to have
   16482             // them trim their memory after the user leaves the UI.  To
   16483             // facilitate this, here we need to determine whether or not it
   16484             // is currently showing UI.
   16485             app.systemNoUi = true;
   16486             if (app == TOP_APP) {
   16487                 app.systemNoUi = false;
   16488             } else if (activitiesSize > 0) {
   16489                 for (int j = 0; j < activitiesSize; j++) {
   16490                     final ActivityRecord r = app.activities.get(j);
   16491                     if (r.visible) {
   16492                         app.systemNoUi = false;
   16493                     }
   16494                 }
   16495             }
   16496             if (!app.systemNoUi) {
   16497                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   16498             }
   16499             return (app.curAdj=app.maxAdj);
   16500         }
   16501 
   16502         app.systemNoUi = false;
   16503 
   16504         // Determine the importance of the process, starting with most
   16505         // important to least, and assign an appropriate OOM adjustment.
   16506         int adj;
   16507         int schedGroup;
   16508         int procState;
   16509         boolean foregroundActivities = false;
   16510         BroadcastQueue queue;
   16511         if (app == TOP_APP) {
   16512             // The last app on the list is the foreground app.
   16513             adj = ProcessList.FOREGROUND_APP_ADJ;
   16514             schedGroup = Process.THREAD_GROUP_DEFAULT;
   16515             app.adjType = "top-activity";
   16516             foregroundActivities = true;
   16517             procState = ActivityManager.PROCESS_STATE_TOP;
   16518         } else if (app.instrumentationClass != null) {
   16519             // Don't want to kill running instrumentation.
   16520             adj = ProcessList.FOREGROUND_APP_ADJ;
   16521             schedGroup = Process.THREAD_GROUP_DEFAULT;
   16522             app.adjType = "instrumentation";
   16523             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16524         } else if ((queue = isReceivingBroadcast(app)) != null) {
   16525             // An app that is currently receiving a broadcast also
   16526             // counts as being in the foreground for OOM killer purposes.
   16527             // It's placed in a sched group based on the nature of the
   16528             // broadcast as reflected by which queue it's active in.
   16529             adj = ProcessList.FOREGROUND_APP_ADJ;
   16530             schedGroup = (queue == mFgBroadcastQueue)
   16531                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16532             app.adjType = "broadcast";
   16533             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   16534         } else if (app.executingServices.size() > 0) {
   16535             // An app that is currently executing a service callback also
   16536             // counts as being in the foreground.
   16537             adj = ProcessList.FOREGROUND_APP_ADJ;
   16538             schedGroup = app.execServicesFg ?
   16539                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16540             app.adjType = "exec-service";
   16541             procState = ActivityManager.PROCESS_STATE_SERVICE;
   16542             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   16543         } else {
   16544             // As far as we know the process is empty.  We may change our mind later.
   16545             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16546             // At this point we don't actually know the adjustment.  Use the cached adj
   16547             // value that the caller wants us to.
   16548             adj = cachedAdj;
   16549             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16550             app.cached = true;
   16551             app.empty = true;
   16552             app.adjType = "cch-empty";
   16553         }
   16554 
   16555         // Examine all activities if not already foreground.
   16556         if (!foregroundActivities && activitiesSize > 0) {
   16557             for (int j = 0; j < activitiesSize; j++) {
   16558                 final ActivityRecord r = app.activities.get(j);
   16559                 if (r.app != app) {
   16560                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   16561                             + app + "?!?");
   16562                     continue;
   16563                 }
   16564                 if (r.visible) {
   16565                     // App has a visible activity; only upgrade adjustment.
   16566                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   16567                         adj = ProcessList.VISIBLE_APP_ADJ;
   16568                         app.adjType = "visible";
   16569                     }
   16570                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   16571                         procState = ActivityManager.PROCESS_STATE_TOP;
   16572                     }
   16573                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   16574                     app.cached = false;
   16575                     app.empty = false;
   16576                     foregroundActivities = true;
   16577                     break;
   16578                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   16579                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16580                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   16581                         app.adjType = "pausing";
   16582                     }
   16583                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   16584                         procState = ActivityManager.PROCESS_STATE_TOP;
   16585                     }
   16586                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   16587                     app.cached = false;
   16588                     app.empty = false;
   16589                     foregroundActivities = true;
   16590                 } else if (r.state == ActivityState.STOPPING) {
   16591                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16592                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   16593                         app.adjType = "stopping";
   16594                     }
   16595                     // For the process state, we will at this point consider the
   16596                     // process to be cached.  It will be cached either as an activity
   16597                     // or empty depending on whether the activity is finishing.  We do
   16598                     // this so that we can treat the process as cached for purposes of
   16599                     // memory trimming (determing current memory level, trim command to
   16600                     // send to process) since there can be an arbitrary number of stopping
   16601                     // processes and they should soon all go into the cached state.
   16602                     if (!r.finishing) {
   16603                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   16604                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   16605                         }
   16606                     }
   16607                     app.cached = false;
   16608                     app.empty = false;
   16609                     foregroundActivities = true;
   16610                 } else {
   16611                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   16612                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   16613                         app.adjType = "cch-act";
   16614                     }
   16615                 }
   16616             }
   16617         }
   16618 
   16619         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16620             if (app.foregroundServices) {
   16621                 // The user is aware of this app, so make it visible.
   16622                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   16623                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16624                 app.cached = false;
   16625                 app.adjType = "fg-service";
   16626                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   16627             } else if (app.forcingToForeground != null) {
   16628                 // The user is aware of this app, so make it visible.
   16629                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   16630                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16631                 app.cached = false;
   16632                 app.adjType = "force-fg";
   16633                 app.adjSource = app.forcingToForeground;
   16634                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   16635             }
   16636         }
   16637 
   16638         if (app == mHeavyWeightProcess) {
   16639             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   16640                 // We don't want to kill the current heavy-weight process.
   16641                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   16642                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16643                 app.cached = false;
   16644                 app.adjType = "heavy";
   16645             }
   16646             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   16647                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   16648             }
   16649         }
   16650 
   16651         if (app == mHomeProcess) {
   16652             if (adj > ProcessList.HOME_APP_ADJ) {
   16653                 // This process is hosting what we currently consider to be the
   16654                 // home app, so we don't want to let it go into the background.
   16655                 adj = ProcessList.HOME_APP_ADJ;
   16656                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16657                 app.cached = false;
   16658                 app.adjType = "home";
   16659             }
   16660             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   16661                 procState = ActivityManager.PROCESS_STATE_HOME;
   16662             }
   16663         }
   16664 
   16665         if (app == mPreviousProcess && app.activities.size() > 0) {
   16666             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   16667                 // This was the previous process that showed UI to the user.
   16668                 // We want to try to keep it around more aggressively, to give
   16669                 // a good experience around switching between two apps.
   16670                 adj = ProcessList.PREVIOUS_APP_ADJ;
   16671                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   16672                 app.cached = false;
   16673                 app.adjType = "previous";
   16674             }
   16675             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   16676                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   16677             }
   16678         }
   16679 
   16680         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   16681                 + " reason=" + app.adjType);
   16682 
   16683         // By default, we use the computed adjustment.  It may be changed if
   16684         // there are applications dependent on our services or providers, but
   16685         // this gives us a baseline and makes sure we don't get into an
   16686         // infinite recursion.
   16687         app.adjSeq = mAdjSeq;
   16688         app.curRawAdj = adj;
   16689         app.hasStartedServices = false;
   16690 
   16691         if (mBackupTarget != null && app == mBackupTarget.app) {
   16692             // If possible we want to avoid killing apps while they're being backed up
   16693             if (adj > ProcessList.BACKUP_APP_ADJ) {
   16694                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   16695                 adj = ProcessList.BACKUP_APP_ADJ;
   16696                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   16697                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   16698                 }
   16699                 app.adjType = "backup";
   16700                 app.cached = false;
   16701             }
   16702             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   16703                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   16704             }
   16705         }
   16706 
   16707         boolean mayBeTop = false;
   16708 
   16709         for (int is = app.services.size()-1;
   16710                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   16711                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   16712                         || procState > ActivityManager.PROCESS_STATE_TOP);
   16713                 is--) {
   16714             ServiceRecord s = app.services.valueAt(is);
   16715             if (s.startRequested) {
   16716                 app.hasStartedServices = true;
   16717                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   16718                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   16719                 }
   16720                 if (app.hasShownUi && app != mHomeProcess) {
   16721                     // If this process has shown some UI, let it immediately
   16722                     // go to the LRU list because it may be pretty heavy with
   16723                     // UI stuff.  We'll tag it with a label just to help
   16724                     // debug and understand what is going on.
   16725                     if (adj > ProcessList.SERVICE_ADJ) {
   16726                         app.adjType = "cch-started-ui-services";
   16727                     }
   16728                 } else {
   16729                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   16730                         // This service has seen some activity within
   16731                         // recent memory, so we will keep its process ahead
   16732                         // of the background processes.
   16733                         if (adj > ProcessList.SERVICE_ADJ) {
   16734                             adj = ProcessList.SERVICE_ADJ;
   16735                             app.adjType = "started-services";
   16736                             app.cached = false;
   16737                         }
   16738                     }
   16739                     // If we have let the service slide into the background
   16740                     // state, still have some text describing what it is doing
   16741                     // even though the service no longer has an impact.
   16742                     if (adj > ProcessList.SERVICE_ADJ) {
   16743                         app.adjType = "cch-started-services";
   16744                     }
   16745                 }
   16746             }
   16747             for (int conni = s.connections.size()-1;
   16748                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   16749                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   16750                             || procState > ActivityManager.PROCESS_STATE_TOP);
   16751                     conni--) {
   16752                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   16753                 for (int i = 0;
   16754                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   16755                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   16756                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   16757                         i++) {
   16758                     // XXX should compute this based on the max of
   16759                     // all connected clients.
   16760                     ConnectionRecord cr = clist.get(i);
   16761                     if (cr.binding.client == app) {
   16762                         // Binding to ourself is not interesting.
   16763                         continue;
   16764                     }
   16765                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   16766                         ProcessRecord client = cr.binding.client;
   16767                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   16768                                 TOP_APP, doingAll, now);
   16769                         int clientProcState = client.curProcState;
   16770                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   16771                             // If the other app is cached for any reason, for purposes here
   16772                             // we are going to consider it empty.  The specific cached state
   16773                             // doesn't propagate except under certain conditions.
   16774                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16775                         }
   16776                         String adjType = null;
   16777                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   16778                             // Not doing bind OOM management, so treat
   16779                             // this guy more like a started service.
   16780                             if (app.hasShownUi && app != mHomeProcess) {
   16781                                 // If this process has shown some UI, let it immediately
   16782                                 // go to the LRU list because it may be pretty heavy with
   16783                                 // UI stuff.  We'll tag it with a label just to help
   16784                                 // debug and understand what is going on.
   16785                                 if (adj > clientAdj) {
   16786                                     adjType = "cch-bound-ui-services";
   16787                                 }
   16788                                 app.cached = false;
   16789                                 clientAdj = adj;
   16790                                 clientProcState = procState;
   16791                             } else {
   16792                                 if (now >= (s.lastActivity
   16793                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   16794                                     // This service has not seen activity within
   16795                                     // recent memory, so allow it to drop to the
   16796                                     // LRU list if there is no other reason to keep
   16797                                     // it around.  We'll also tag it with a label just
   16798                                     // to help debug and undertand what is going on.
   16799                                     if (adj > clientAdj) {
   16800                                         adjType = "cch-bound-services";
   16801                                     }
   16802                                     clientAdj = adj;
   16803                                 }
   16804                             }
   16805                         }
   16806                         if (adj > clientAdj) {
   16807                             // If this process has recently shown UI, and
   16808                             // the process that is binding to it is less
   16809                             // important than being visible, then we don't
   16810                             // care about the binding as much as we care
   16811                             // about letting this process get into the LRU
   16812                             // list to be killed and restarted if needed for
   16813                             // memory.
   16814                             if (app.hasShownUi && app != mHomeProcess
   16815                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16816                                 adjType = "cch-bound-ui-services";
   16817                             } else {
   16818                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   16819                                         |Context.BIND_IMPORTANT)) != 0) {
   16820                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
   16821                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
   16822                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   16823                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   16824                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16825                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   16826                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   16827                                     adj = clientAdj;
   16828                                 } else {
   16829                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   16830                                         adj = ProcessList.VISIBLE_APP_ADJ;
   16831                                     }
   16832                                 }
   16833                                 if (!client.cached) {
   16834                                     app.cached = false;
   16835                                 }
   16836                                 adjType = "service";
   16837                             }
   16838                         }
   16839                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   16840                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   16841                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   16842                             }
   16843                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   16844                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   16845                                     // Special handling of clients who are in the top state.
   16846                                     // We *may* want to consider this process to be in the
   16847                                     // top state as well, but only if there is not another
   16848                                     // reason for it to be running.  Being on the top is a
   16849                                     // special state, meaning you are specifically running
   16850                                     // for the current top app.  If the process is already
   16851                                     // running in the background for some other reason, it
   16852                                     // is more important to continue considering it to be
   16853                                     // in the background state.
   16854                                     mayBeTop = true;
   16855                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16856                                 } else {
   16857                                     // Special handling for above-top states (persistent
   16858                                     // processes).  These should not bring the current process
   16859                                     // into the top state, since they are not on top.  Instead
   16860                                     // give them the best state after that.
   16861                                     clientProcState =
   16862                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16863                                 }
   16864                             }
   16865                         } else {
   16866                             if (clientProcState <
   16867                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   16868                                 clientProcState =
   16869                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   16870                             }
   16871                         }
   16872                         if (procState > clientProcState) {
   16873                             procState = clientProcState;
   16874                         }
   16875                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   16876                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   16877                             app.pendingUiClean = true;
   16878                         }
   16879                         if (adjType != null) {
   16880                             app.adjType = adjType;
   16881                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   16882                                     .REASON_SERVICE_IN_USE;
   16883                             app.adjSource = cr.binding.client;
   16884                             app.adjSourceProcState = clientProcState;
   16885                             app.adjTarget = s.name;
   16886                         }
   16887                     }
   16888                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
   16889                         app.treatLikeActivity = true;
   16890                     }
   16891                     final ActivityRecord a = cr.activity;
   16892                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   16893                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   16894                                 (a.visible || a.state == ActivityState.RESUMED
   16895                                  || a.state == ActivityState.PAUSING)) {
   16896                             adj = ProcessList.FOREGROUND_APP_ADJ;
   16897                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   16898                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   16899                             }
   16900                             app.cached = false;
   16901                             app.adjType = "service";
   16902                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   16903                                     .REASON_SERVICE_IN_USE;
   16904                             app.adjSource = a;
   16905                             app.adjSourceProcState = procState;
   16906                             app.adjTarget = s.name;
   16907                         }
   16908                     }
   16909                 }
   16910             }
   16911         }
   16912 
   16913         for (int provi = app.pubProviders.size()-1;
   16914                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   16915                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   16916                         || procState > ActivityManager.PROCESS_STATE_TOP);
   16917                 provi--) {
   16918             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   16919             for (int i = cpr.connections.size()-1;
   16920                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   16921                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   16922                             || procState > ActivityManager.PROCESS_STATE_TOP);
   16923                     i--) {
   16924                 ContentProviderConnection conn = cpr.connections.get(i);
   16925                 ProcessRecord client = conn.client;
   16926                 if (client == app) {
   16927                     // Being our own client is not interesting.
   16928                     continue;
   16929                 }
   16930                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   16931                 int clientProcState = client.curProcState;
   16932                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   16933                     // If the other app is cached for any reason, for purposes here
   16934                     // we are going to consider it empty.
   16935                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16936                 }
   16937                 if (adj > clientAdj) {
   16938                     if (app.hasShownUi && app != mHomeProcess
   16939                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   16940                         app.adjType = "cch-ui-provider";
   16941                     } else {
   16942                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   16943                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   16944                         app.adjType = "provider";
   16945                     }
   16946                     app.cached &= client.cached;
   16947                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   16948                             .REASON_PROVIDER_IN_USE;
   16949                     app.adjSource = client;
   16950                     app.adjSourceProcState = clientProcState;
   16951                     app.adjTarget = cpr.name;
   16952                 }
   16953                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   16954                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   16955                         // Special handling of clients who are in the top state.
   16956                         // We *may* want to consider this process to be in the
   16957                         // top state as well, but only if there is not another
   16958                         // reason for it to be running.  Being on the top is a
   16959                         // special state, meaning you are specifically running
   16960                         // for the current top app.  If the process is already
   16961                         // running in the background for some other reason, it
   16962                         // is more important to continue considering it to be
   16963                         // in the background state.
   16964                         mayBeTop = true;
   16965                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   16966                     } else {
   16967                         // Special handling for above-top states (persistent
   16968                         // processes).  These should not bring the current process
   16969                         // into the top state, since they are not on top.  Instead
   16970                         // give them the best state after that.
   16971                         clientProcState =
   16972                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16973                     }
   16974                 }
   16975                 if (procState > clientProcState) {
   16976                     procState = clientProcState;
   16977                 }
   16978                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   16979                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   16980                 }
   16981             }
   16982             // If the provider has external (non-framework) process
   16983             // dependencies, ensure that its adjustment is at least
   16984             // FOREGROUND_APP_ADJ.
   16985             if (cpr.hasExternalProcessHandles()) {
   16986                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   16987                     adj = ProcessList.FOREGROUND_APP_ADJ;
   16988                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   16989                     app.cached = false;
   16990                     app.adjType = "provider";
   16991                     app.adjTarget = cpr.name;
   16992                 }
   16993                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   16994                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   16995                 }
   16996             }
   16997         }
   16998 
   16999         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   17000             // A client of one of our services or providers is in the top state.  We
   17001             // *may* want to be in the top state, but not if we are already running in
   17002             // the background for some other reason.  For the decision here, we are going
   17003             // to pick out a few specific states that we want to remain in when a client
   17004             // is top (states that tend to be longer-term) and otherwise allow it to go
   17005             // to the top state.
   17006             switch (procState) {
   17007                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   17008                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   17009                 case ActivityManager.PROCESS_STATE_SERVICE:
   17010                     // These all are longer-term states, so pull them up to the top
   17011                     // of the background states, but not all the way to the top state.
   17012                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   17013                     break;
   17014                 default:
   17015                     // Otherwise, top is a better choice, so take it.
   17016                     procState = ActivityManager.PROCESS_STATE_TOP;
   17017                     break;
   17018             }
   17019         }
   17020 
   17021         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   17022             if (app.hasClientActivities) {
   17023                 // This is a cached process, but with client activities.  Mark it so.
   17024                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   17025                 app.adjType = "cch-client-act";
   17026             } else if (app.treatLikeActivity) {
   17027                 // This is a cached process, but somebody wants us to treat it like it has
   17028                 // an activity, okay!
   17029                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   17030                 app.adjType = "cch-as-act";
   17031             }
   17032         }
   17033 
   17034         if (adj == ProcessList.SERVICE_ADJ) {
   17035             if (doingAll) {
   17036                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   17037                 mNewNumServiceProcs++;
   17038                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   17039                 if (!app.serviceb) {
   17040                     // This service isn't far enough down on the LRU list to
   17041                     // normally be a B service, but if we are low on RAM and it
   17042                     // is large we want to force it down since we would prefer to
   17043                     // keep launcher over it.
   17044                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   17045                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   17046                         app.serviceHighRam = true;
   17047                         app.serviceb = true;
   17048                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   17049                     } else {
   17050                         mNewNumAServiceProcs++;
   17051                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   17052                     }
   17053                 } else {
   17054                     app.serviceHighRam = false;
   17055                 }
   17056             }
   17057             if (app.serviceb) {
   17058                 adj = ProcessList.SERVICE_B_ADJ;
   17059             }
   17060         }
   17061 
   17062         app.curRawAdj = adj;
   17063 
   17064         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   17065         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   17066         if (adj > app.maxAdj) {
   17067             adj = app.maxAdj;
   17068             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   17069                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   17070             }
   17071         }
   17072 
   17073         // Do final modification to adj.  Everything we do between here and applying
   17074         // the final setAdj must be done in this function, because we will also use
   17075         // it when computing the final cached adj later.  Note that we don't need to
   17076         // worry about this for max adj above, since max adj will always be used to
   17077         // keep it out of the cached vaues.
   17078         app.curAdj = app.modifyRawOomAdj(adj);
   17079         app.curSchedGroup = schedGroup;
   17080         app.curProcState = procState;
   17081         app.foregroundActivities = foregroundActivities;
   17082 
   17083         return app.curRawAdj;
   17084     }
   17085 
   17086     /**
   17087      * Schedule PSS collection of a process.
   17088      */
   17089     void requestPssLocked(ProcessRecord proc, int procState) {
   17090         if (mPendingPssProcesses.contains(proc)) {
   17091             return;
   17092         }
   17093         if (mPendingPssProcesses.size() == 0) {
   17094             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17095         }
   17096         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   17097         proc.pssProcState = procState;
   17098         mPendingPssProcesses.add(proc);
   17099     }
   17100 
   17101     /**
   17102      * Schedule PSS collection of all processes.
   17103      */
   17104     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   17105         if (!always) {
   17106             if (now < (mLastFullPssTime +
   17107                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   17108                 return;
   17109             }
   17110         }
   17111         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   17112         mLastFullPssTime = now;
   17113         mFullPssPending = true;
   17114         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   17115         mPendingPssProcesses.clear();
   17116         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   17117             ProcessRecord app = mLruProcesses.get(i);
   17118             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   17119                 app.pssProcState = app.setProcState;
   17120                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17121                         isSleeping(), now);
   17122                 mPendingPssProcesses.add(app);
   17123             }
   17124         }
   17125         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   17126     }
   17127 
   17128     /**
   17129      * Ask a given process to GC right now.
   17130      */
   17131     final void performAppGcLocked(ProcessRecord app) {
   17132         try {
   17133             app.lastRequestedGc = SystemClock.uptimeMillis();
   17134             if (app.thread != null) {
   17135                 if (app.reportLowMemory) {
   17136                     app.reportLowMemory = false;
   17137                     app.thread.scheduleLowMemory();
   17138                 } else {
   17139                     app.thread.processInBackground();
   17140                 }
   17141             }
   17142         } catch (Exception e) {
   17143             // whatever.
   17144         }
   17145     }
   17146 
   17147     /**
   17148      * Returns true if things are idle enough to perform GCs.
   17149      */
   17150     private final boolean canGcNowLocked() {
   17151         boolean processingBroadcasts = false;
   17152         for (BroadcastQueue q : mBroadcastQueues) {
   17153             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   17154                 processingBroadcasts = true;
   17155             }
   17156         }
   17157         return !processingBroadcasts
   17158                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
   17159     }
   17160 
   17161     /**
   17162      * Perform GCs on all processes that are waiting for it, but only
   17163      * if things are idle.
   17164      */
   17165     final void performAppGcsLocked() {
   17166         final int N = mProcessesToGc.size();
   17167         if (N <= 0) {
   17168             return;
   17169         }
   17170         if (canGcNowLocked()) {
   17171             while (mProcessesToGc.size() > 0) {
   17172                 ProcessRecord proc = mProcessesToGc.remove(0);
   17173                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   17174                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   17175                             <= SystemClock.uptimeMillis()) {
   17176                         // To avoid spamming the system, we will GC processes one
   17177                         // at a time, waiting a few seconds between each.
   17178                         performAppGcLocked(proc);
   17179                         scheduleAppGcsLocked();
   17180                         return;
   17181                     } else {
   17182                         // It hasn't been long enough since we last GCed this
   17183                         // process...  put it in the list to wait for its time.
   17184                         addProcessToGcListLocked(proc);
   17185                         break;
   17186                     }
   17187                 }
   17188             }
   17189 
   17190             scheduleAppGcsLocked();
   17191         }
   17192     }
   17193 
   17194     /**
   17195      * If all looks good, perform GCs on all processes waiting for them.
   17196      */
   17197     final void performAppGcsIfAppropriateLocked() {
   17198         if (canGcNowLocked()) {
   17199             performAppGcsLocked();
   17200             return;
   17201         }
   17202         // Still not idle, wait some more.
   17203         scheduleAppGcsLocked();
   17204     }
   17205 
   17206     /**
   17207      * Schedule the execution of all pending app GCs.
   17208      */
   17209     final void scheduleAppGcsLocked() {
   17210         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   17211 
   17212         if (mProcessesToGc.size() > 0) {
   17213             // Schedule a GC for the time to the next process.
   17214             ProcessRecord proc = mProcessesToGc.get(0);
   17215             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   17216 
   17217             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   17218             long now = SystemClock.uptimeMillis();
   17219             if (when < (now+GC_TIMEOUT)) {
   17220                 when = now + GC_TIMEOUT;
   17221             }
   17222             mHandler.sendMessageAtTime(msg, when);
   17223         }
   17224     }
   17225 
   17226     /**
   17227      * Add a process to the array of processes waiting to be GCed.  Keeps the
   17228      * list in sorted order by the last GC time.  The process can't already be
   17229      * on the list.
   17230      */
   17231     final void addProcessToGcListLocked(ProcessRecord proc) {
   17232         boolean added = false;
   17233         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   17234             if (mProcessesToGc.get(i).lastRequestedGc <
   17235                     proc.lastRequestedGc) {
   17236                 added = true;
   17237                 mProcessesToGc.add(i+1, proc);
   17238                 break;
   17239             }
   17240         }
   17241         if (!added) {
   17242             mProcessesToGc.add(0, proc);
   17243         }
   17244     }
   17245 
   17246     /**
   17247      * Set up to ask a process to GC itself.  This will either do it
   17248      * immediately, or put it on the list of processes to gc the next
   17249      * time things are idle.
   17250      */
   17251     final void scheduleAppGcLocked(ProcessRecord app) {
   17252         long now = SystemClock.uptimeMillis();
   17253         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   17254             return;
   17255         }
   17256         if (!mProcessesToGc.contains(app)) {
   17257             addProcessToGcListLocked(app);
   17258             scheduleAppGcsLocked();
   17259         }
   17260     }
   17261 
   17262     final void checkExcessivePowerUsageLocked(boolean doKills) {
   17263         updateCpuStatsNow();
   17264 
   17265         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17266         boolean doWakeKills = doKills;
   17267         boolean doCpuKills = doKills;
   17268         if (mLastPowerCheckRealtime == 0) {
   17269             doWakeKills = false;
   17270         }
   17271         if (mLastPowerCheckUptime == 0) {
   17272             doCpuKills = false;
   17273         }
   17274         if (stats.isScreenOn()) {
   17275             doWakeKills = false;
   17276         }
   17277         final long curRealtime = SystemClock.elapsedRealtime();
   17278         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   17279         final long curUptime = SystemClock.uptimeMillis();
   17280         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   17281         mLastPowerCheckRealtime = curRealtime;
   17282         mLastPowerCheckUptime = curUptime;
   17283         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   17284             doWakeKills = false;
   17285         }
   17286         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   17287             doCpuKills = false;
   17288         }
   17289         int i = mLruProcesses.size();
   17290         while (i > 0) {
   17291             i--;
   17292             ProcessRecord app = mLruProcesses.get(i);
   17293             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   17294                 long wtime;
   17295                 synchronized (stats) {
   17296                     wtime = stats.getProcessWakeTime(app.info.uid,
   17297                             app.pid, curRealtime);
   17298                 }
   17299                 long wtimeUsed = wtime - app.lastWakeTime;
   17300                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   17301                 if (DEBUG_POWER) {
   17302                     StringBuilder sb = new StringBuilder(128);
   17303                     sb.append("Wake for ");
   17304                     app.toShortString(sb);
   17305                     sb.append(": over ");
   17306                     TimeUtils.formatDuration(realtimeSince, sb);
   17307                     sb.append(" used ");
   17308                     TimeUtils.formatDuration(wtimeUsed, sb);
   17309                     sb.append(" (");
   17310                     sb.append((wtimeUsed*100)/realtimeSince);
   17311                     sb.append("%)");
   17312                     Slog.i(TAG, sb.toString());
   17313                     sb.setLength(0);
   17314                     sb.append("CPU for ");
   17315                     app.toShortString(sb);
   17316                     sb.append(": over ");
   17317                     TimeUtils.formatDuration(uptimeSince, sb);
   17318                     sb.append(" used ");
   17319                     TimeUtils.formatDuration(cputimeUsed, sb);
   17320                     sb.append(" (");
   17321                     sb.append((cputimeUsed*100)/uptimeSince);
   17322                     sb.append("%)");
   17323                     Slog.i(TAG, sb.toString());
   17324                 }
   17325                 // If a process has held a wake lock for more
   17326                 // than 50% of the time during this period,
   17327                 // that sounds bad.  Kill!
   17328                 if (doWakeKills && realtimeSince > 0
   17329                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   17330                     synchronized (stats) {
   17331                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   17332                                 realtimeSince, wtimeUsed);
   17333                     }
   17334                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
   17335                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   17336                 } else if (doCpuKills && uptimeSince > 0
   17337                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
   17338                     synchronized (stats) {
   17339                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   17340                                 uptimeSince, cputimeUsed);
   17341                     }
   17342                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
   17343                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   17344                 } else {
   17345                     app.lastWakeTime = wtime;
   17346                     app.lastCpuTime = app.curCpuTime;
   17347                 }
   17348             }
   17349         }
   17350     }
   17351 
   17352     private final boolean applyOomAdjLocked(ProcessRecord app,
   17353             ProcessRecord TOP_APP, boolean doingAll, long now) {
   17354         boolean success = true;
   17355 
   17356         if (app.curRawAdj != app.setRawAdj) {
   17357             app.setRawAdj = app.curRawAdj;
   17358         }
   17359 
   17360         int changes = 0;
   17361 
   17362         if (app.curAdj != app.setAdj) {
   17363             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
   17364             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   17365                 TAG, "Set " + app.pid + " " + app.processName +
   17366                 " adj " + app.curAdj + ": " + app.adjType);
   17367             app.setAdj = app.curAdj;
   17368         }
   17369 
   17370         if (app.setSchedGroup != app.curSchedGroup) {
   17371             app.setSchedGroup = app.curSchedGroup;
   17372             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17373                     "Setting process group of " + app.processName
   17374                     + " to " + app.curSchedGroup);
   17375             if (app.waitingToKill != null &&
   17376                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   17377                 app.kill(app.waitingToKill, true);
   17378                 success = false;
   17379             } else {
   17380                 if (true) {
   17381                     long oldId = Binder.clearCallingIdentity();
   17382                     try {
   17383                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   17384                     } catch (Exception e) {
   17385                         Slog.w(TAG, "Failed setting process group of " + app.pid
   17386                                 + " to " + app.curSchedGroup);
   17387                         e.printStackTrace();
   17388                     } finally {
   17389                         Binder.restoreCallingIdentity(oldId);
   17390                     }
   17391                 } else {
   17392                     if (app.thread != null) {
   17393                         try {
   17394                             app.thread.setSchedulingGroup(app.curSchedGroup);
   17395                         } catch (RemoteException e) {
   17396                         }
   17397                     }
   17398                 }
   17399                 Process.setSwappiness(app.pid,
   17400                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   17401             }
   17402         }
   17403         if (app.repForegroundActivities != app.foregroundActivities) {
   17404             app.repForegroundActivities = app.foregroundActivities;
   17405             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   17406         }
   17407         if (app.repProcState != app.curProcState) {
   17408             app.repProcState = app.curProcState;
   17409             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
   17410             if (app.thread != null) {
   17411                 try {
   17412                     if (false) {
   17413                         //RuntimeException h = new RuntimeException("here");
   17414                         Slog.i(TAG, "Sending new process state " + app.repProcState
   17415                                 + " to " + app /*, h*/);
   17416                     }
   17417                     app.thread.setProcessState(app.repProcState);
   17418                 } catch (RemoteException e) {
   17419                 }
   17420             }
   17421         }
   17422         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   17423                 app.setProcState)) {
   17424             app.lastStateTime = now;
   17425             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   17426                     isSleeping(), now);
   17427             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   17428                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   17429                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   17430                     + (app.nextPssTime-now) + ": " + app);
   17431         } else {
   17432             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   17433                     && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
   17434                 requestPssLocked(app, app.setProcState);
   17435                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   17436                         isSleeping(), now);
   17437             } else if (false && DEBUG_PSS) {
   17438                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   17439             }
   17440         }
   17441         if (app.setProcState != app.curProcState) {
   17442             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17443                     "Proc state change of " + app.processName
   17444                     + " to " + app.curProcState);
   17445             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17446             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
   17447             if (setImportant && !curImportant) {
   17448                 // This app is no longer something we consider important enough to allow to
   17449                 // use arbitrary amounts of battery power.  Note
   17450                 // its current wake lock time to later know to kill it if
   17451                 // it is not behaving well.
   17452                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   17453                 synchronized (stats) {
   17454                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   17455                             app.pid, SystemClock.elapsedRealtime());
   17456                 }
   17457                 app.lastCpuTime = app.curCpuTime;
   17458 
   17459             }
   17460             app.setProcState = app.curProcState;
   17461             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   17462                 app.notCachedSinceIdle = false;
   17463             }
   17464             if (!doingAll) {
   17465                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
   17466             } else {
   17467                 app.procStateChanged = true;
   17468             }
   17469         }
   17470 
   17471         if (changes != 0) {
   17472             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   17473             int i = mPendingProcessChanges.size()-1;
   17474             ProcessChangeItem item = null;
   17475             while (i >= 0) {
   17476                 item = mPendingProcessChanges.get(i);
   17477                 if (item.pid == app.pid) {
   17478                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   17479                     break;
   17480                 }
   17481                 i--;
   17482             }
   17483             if (i < 0) {
   17484                 // No existing item in pending changes; need a new one.
   17485                 final int NA = mAvailProcessChanges.size();
   17486                 if (NA > 0) {
   17487                     item = mAvailProcessChanges.remove(NA-1);
   17488                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   17489                 } else {
   17490                     item = new ProcessChangeItem();
   17491                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   17492                 }
   17493                 item.changes = 0;
   17494                 item.pid = app.pid;
   17495                 item.uid = app.info.uid;
   17496                 if (mPendingProcessChanges.size() == 0) {
   17497                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   17498                             "*** Enqueueing dispatch processes changed!");
   17499                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   17500                 }
   17501                 mPendingProcessChanges.add(item);
   17502             }
   17503             item.changes |= changes;
   17504             item.processState = app.repProcState;
   17505             item.foregroundActivities = app.repForegroundActivities;
   17506             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   17507                     + Integer.toHexString(System.identityHashCode(item))
   17508                     + " " + app.toShortString() + ": changes=" + item.changes
   17509                     + " procState=" + item.processState
   17510                     + " foreground=" + item.foregroundActivities
   17511                     + " type=" + app.adjType + " source=" + app.adjSource
   17512                     + " target=" + app.adjTarget);
   17513         }
   17514 
   17515         return success;
   17516     }
   17517 
   17518     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
   17519         if (proc.thread != null) {
   17520             if (proc.baseProcessTracker != null) {
   17521                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   17522             }
   17523             if (proc.repProcState >= 0) {
   17524                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
   17525                         proc.repProcState);
   17526             }
   17527         }
   17528     }
   17529 
   17530     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   17531             ProcessRecord TOP_APP, boolean doingAll, long now) {
   17532         if (app.thread == null) {
   17533             return false;
   17534         }
   17535 
   17536         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   17537 
   17538         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
   17539     }
   17540 
   17541     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
   17542             boolean oomAdj) {
   17543         if (isForeground != proc.foregroundServices) {
   17544             proc.foregroundServices = isForeground;
   17545             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
   17546                     proc.info.uid);
   17547             if (isForeground) {
   17548                 if (curProcs == null) {
   17549                     curProcs = new ArrayList<ProcessRecord>();
   17550                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
   17551                 }
   17552                 if (!curProcs.contains(proc)) {
   17553                     curProcs.add(proc);
   17554                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
   17555                             proc.info.packageName, proc.info.uid);
   17556                 }
   17557             } else {
   17558                 if (curProcs != null) {
   17559                     if (curProcs.remove(proc)) {
   17560                         mBatteryStatsService.noteEvent(
   17561                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
   17562                                 proc.info.packageName, proc.info.uid);
   17563                         if (curProcs.size() <= 0) {
   17564                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
   17565                         }
   17566                     }
   17567                 }
   17568             }
   17569             if (oomAdj) {
   17570                 updateOomAdjLocked();
   17571             }
   17572         }
   17573     }
   17574 
   17575     private final ActivityRecord resumedAppLocked() {
   17576         ActivityRecord act = mStackSupervisor.resumedAppLocked();
   17577         String pkg;
   17578         int uid;
   17579         if (act != null) {
   17580             pkg = act.packageName;
   17581             uid = act.info.applicationInfo.uid;
   17582         } else {
   17583             pkg = null;
   17584             uid = -1;
   17585         }
   17586         // Has the UID or resumed package name changed?
   17587         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
   17588                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
   17589             if (mCurResumedPackage != null) {
   17590                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
   17591                         mCurResumedPackage, mCurResumedUid);
   17592             }
   17593             mCurResumedPackage = pkg;
   17594             mCurResumedUid = uid;
   17595             if (mCurResumedPackage != null) {
   17596                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
   17597                         mCurResumedPackage, mCurResumedUid);
   17598             }
   17599         }
   17600         return act;
   17601     }
   17602 
   17603     final boolean updateOomAdjLocked(ProcessRecord app) {
   17604         final ActivityRecord TOP_ACT = resumedAppLocked();
   17605         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   17606         final boolean wasCached = app.cached;
   17607 
   17608         mAdjSeq++;
   17609 
   17610         // This is the desired cached adjusment we want to tell it to use.
   17611         // If our app is currently cached, we know it, and that is it.  Otherwise,
   17612         // we don't know it yet, and it needs to now be cached we will then
   17613         // need to do a complete oom adj.
   17614         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   17615                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   17616         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
   17617                 SystemClock.uptimeMillis());
   17618         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   17619             // Changed to/from cached state, so apps after it in the LRU
   17620             // list may also be changed.
   17621             updateOomAdjLocked();
   17622         }
   17623         return success;
   17624     }
   17625 
   17626     final void updateOomAdjLocked() {
   17627         final ActivityRecord TOP_ACT = resumedAppLocked();
   17628         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   17629         final long now = SystemClock.uptimeMillis();
   17630         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   17631         final int N = mLruProcesses.size();
   17632 
   17633         if (false) {
   17634             RuntimeException e = new RuntimeException();
   17635             e.fillInStackTrace();
   17636             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   17637         }
   17638 
   17639         mAdjSeq++;
   17640         mNewNumServiceProcs = 0;
   17641         mNewNumAServiceProcs = 0;
   17642 
   17643         final int emptyProcessLimit;
   17644         final int cachedProcessLimit;
   17645         if (mProcessLimit <= 0) {
   17646             emptyProcessLimit = cachedProcessLimit = 0;
   17647         } else if (mProcessLimit == 1) {
   17648             emptyProcessLimit = 1;
   17649             cachedProcessLimit = 0;
   17650         } else {
   17651             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   17652             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   17653         }
   17654 
   17655         // Let's determine how many processes we have running vs.
   17656         // how many slots we have for background processes; we may want
   17657         // to put multiple processes in a slot of there are enough of
   17658         // them.
   17659         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   17660                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   17661         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   17662         if (numEmptyProcs > cachedProcessLimit) {
   17663             // If there are more empty processes than our limit on cached
   17664             // processes, then use the cached process limit for the factor.
   17665             // This ensures that the really old empty processes get pushed
   17666             // down to the bottom, so if we are running low on memory we will
   17667             // have a better chance at keeping around more cached processes
   17668             // instead of a gazillion empty processes.
   17669             numEmptyProcs = cachedProcessLimit;
   17670         }
   17671         int emptyFactor = numEmptyProcs/numSlots;
   17672         if (emptyFactor < 1) emptyFactor = 1;
   17673         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   17674         if (cachedFactor < 1) cachedFactor = 1;
   17675         int stepCached = 0;
   17676         int stepEmpty = 0;
   17677         int numCached = 0;
   17678         int numEmpty = 0;
   17679         int numTrimming = 0;
   17680 
   17681         mNumNonCachedProcs = 0;
   17682         mNumCachedHiddenProcs = 0;
   17683 
   17684         // First update the OOM adjustment for each of the
   17685         // application processes based on their current state.
   17686         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   17687         int nextCachedAdj = curCachedAdj+1;
   17688         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   17689         int nextEmptyAdj = curEmptyAdj+2;
   17690         for (int i=N-1; i>=0; i--) {
   17691             ProcessRecord app = mLruProcesses.get(i);
   17692             if (!app.killedByAm && app.thread != null) {
   17693                 app.procStateChanged = false;
   17694                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   17695 
   17696                 // If we haven't yet assigned the final cached adj
   17697                 // to the process, do that now.
   17698                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   17699                     switch (app.curProcState) {
   17700                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   17701                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   17702                             // This process is a cached process holding activities...
   17703                             // assign it the next cached value for that type, and then
   17704                             // step that cached level.
   17705                             app.curRawAdj = curCachedAdj;
   17706                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   17707                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
   17708                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   17709                                     + ")");
   17710                             if (curCachedAdj != nextCachedAdj) {
   17711                                 stepCached++;
   17712                                 if (stepCached >= cachedFactor) {
   17713                                     stepCached = 0;
   17714                                     curCachedAdj = nextCachedAdj;
   17715                                     nextCachedAdj += 2;
   17716                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   17717                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   17718                                     }
   17719                                 }
   17720                             }
   17721                             break;
   17722                         default:
   17723                             // For everything else, assign next empty cached process
   17724                             // level and bump that up.  Note that this means that
   17725                             // long-running services that have dropped down to the
   17726                             // cached level will be treated as empty (since their process
   17727                             // state is still as a service), which is what we want.
   17728                             app.curRawAdj = curEmptyAdj;
   17729                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   17730                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
   17731                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   17732                                     + ")");
   17733                             if (curEmptyAdj != nextEmptyAdj) {
   17734                                 stepEmpty++;
   17735                                 if (stepEmpty >= emptyFactor) {
   17736                                     stepEmpty = 0;
   17737                                     curEmptyAdj = nextEmptyAdj;
   17738                                     nextEmptyAdj += 2;
   17739                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   17740                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   17741                                     }
   17742                                 }
   17743                             }
   17744                             break;
   17745                     }
   17746                 }
   17747 
   17748                 applyOomAdjLocked(app, TOP_APP, true, now);
   17749 
   17750                 // Count the number of process types.
   17751                 switch (app.curProcState) {
   17752                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   17753                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   17754                         mNumCachedHiddenProcs++;
   17755                         numCached++;
   17756                         if (numCached > cachedProcessLimit) {
   17757                             app.kill("cached #" + numCached, true);
   17758                         }
   17759                         break;
   17760                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   17761                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   17762                                 && app.lastActivityTime < oldTime) {
   17763                             app.kill("empty for "
   17764                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   17765                                     / 1000) + "s", true);
   17766                         } else {
   17767                             numEmpty++;
   17768                             if (numEmpty > emptyProcessLimit) {
   17769                                 app.kill("empty #" + numEmpty, true);
   17770                             }
   17771                         }
   17772                         break;
   17773                     default:
   17774                         mNumNonCachedProcs++;
   17775                         break;
   17776                 }
   17777 
   17778                 if (app.isolated && app.services.size() <= 0) {
   17779                     // If this is an isolated process, and there are no
   17780                     // services running in it, then the process is no longer
   17781                     // needed.  We agressively kill these because we can by
   17782                     // definition not re-use the same process again, and it is
   17783                     // good to avoid having whatever code was running in them
   17784                     // left sitting around after no longer needed.
   17785                     app.kill("isolated not needed", true);
   17786                 }
   17787 
   17788                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   17789                         && !app.killedByAm) {
   17790                     numTrimming++;
   17791                 }
   17792             }
   17793         }
   17794 
   17795         mNumServiceProcs = mNewNumServiceProcs;
   17796 
   17797         // Now determine the memory trimming level of background processes.
   17798         // Unfortunately we need to start at the back of the list to do this
   17799         // properly.  We only do this if the number of background apps we
   17800         // are managing to keep around is less than half the maximum we desire;
   17801         // if we are keeping a good number around, we'll let them use whatever
   17802         // memory they want.
   17803         final int numCachedAndEmpty = numCached + numEmpty;
   17804         int memFactor;
   17805         if (numCached <= ProcessList.TRIM_CACHED_APPS
   17806                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   17807             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   17808                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   17809             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   17810                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   17811             } else {
   17812                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   17813             }
   17814         } else {
   17815             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   17816         }
   17817         // We always allow the memory level to go up (better).  We only allow it to go
   17818         // down if we are in a state where that is allowed, *and* the total number of processes
   17819         // has gone down since last time.
   17820         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   17821                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   17822                 + " last=" + mLastNumProcesses);
   17823         if (memFactor > mLastMemoryLevel) {
   17824             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   17825                 memFactor = mLastMemoryLevel;
   17826                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   17827             }
   17828         }
   17829         mLastMemoryLevel = memFactor;
   17830         mLastNumProcesses = mLruProcesses.size();
   17831         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
   17832         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   17833         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   17834             if (mLowRamStartTime == 0) {
   17835                 mLowRamStartTime = now;
   17836             }
   17837             int step = 0;
   17838             int fgTrimLevel;
   17839             switch (memFactor) {
   17840                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   17841                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   17842                     break;
   17843                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   17844                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   17845                     break;
   17846                 default:
   17847                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   17848                     break;
   17849             }
   17850             int factor = numTrimming/3;
   17851             int minFactor = 2;
   17852             if (mHomeProcess != null) minFactor++;
   17853             if (mPreviousProcess != null) minFactor++;
   17854             if (factor < minFactor) factor = minFactor;
   17855             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   17856             for (int i=N-1; i>=0; i--) {
   17857                 ProcessRecord app = mLruProcesses.get(i);
   17858                 if (allChanged || app.procStateChanged) {
   17859                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   17860                     app.procStateChanged = false;
   17861                 }
   17862                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   17863                         && !app.killedByAm) {
   17864                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   17865                         try {
   17866                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17867                                     "Trimming memory of " + app.processName
   17868                                     + " to " + curLevel);
   17869                             app.thread.scheduleTrimMemory(curLevel);
   17870                         } catch (RemoteException e) {
   17871                         }
   17872                         if (false) {
   17873                             // For now we won't do this; our memory trimming seems
   17874                             // to be good enough at this point that destroying
   17875                             // activities causes more harm than good.
   17876                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   17877                                     && app != mHomeProcess && app != mPreviousProcess) {
   17878                                 // Need to do this on its own message because the stack may not
   17879                                 // be in a consistent state at this point.
   17880                                 // For these apps we will also finish their activities
   17881                                 // to help them free memory.
   17882                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   17883                             }
   17884                         }
   17885                     }
   17886                     app.trimMemoryLevel = curLevel;
   17887                     step++;
   17888                     if (step >= factor) {
   17889                         step = 0;
   17890                         switch (curLevel) {
   17891                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   17892                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   17893                                 break;
   17894                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   17895                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   17896                                 break;
   17897                         }
   17898                     }
   17899                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   17900                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   17901                             && app.thread != null) {
   17902                         try {
   17903                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17904                                     "Trimming memory of heavy-weight " + app.processName
   17905                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   17906                             app.thread.scheduleTrimMemory(
   17907                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   17908                         } catch (RemoteException e) {
   17909                         }
   17910                     }
   17911                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   17912                 } else {
   17913                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   17914                             || app.systemNoUi) && app.pendingUiClean) {
   17915                         // If this application is now in the background and it
   17916                         // had done UI, then give it the special trim level to
   17917                         // have it free UI resources.
   17918                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   17919                         if (app.trimMemoryLevel < level && app.thread != null) {
   17920                             try {
   17921                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17922                                         "Trimming memory of bg-ui " + app.processName
   17923                                         + " to " + level);
   17924                                 app.thread.scheduleTrimMemory(level);
   17925                             } catch (RemoteException e) {
   17926                             }
   17927                         }
   17928                         app.pendingUiClean = false;
   17929                     }
   17930                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   17931                         try {
   17932                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17933                                     "Trimming memory of fg " + app.processName
   17934                                     + " to " + fgTrimLevel);
   17935                             app.thread.scheduleTrimMemory(fgTrimLevel);
   17936                         } catch (RemoteException e) {
   17937                         }
   17938                     }
   17939                     app.trimMemoryLevel = fgTrimLevel;
   17940                 }
   17941             }
   17942         } else {
   17943             if (mLowRamStartTime != 0) {
   17944                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   17945                 mLowRamStartTime = 0;
   17946             }
   17947             for (int i=N-1; i>=0; i--) {
   17948                 ProcessRecord app = mLruProcesses.get(i);
   17949                 if (allChanged || app.procStateChanged) {
   17950                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
   17951                     app.procStateChanged = false;
   17952                 }
   17953                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   17954                         || app.systemNoUi) && app.pendingUiClean) {
   17955                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   17956                             && app.thread != null) {
   17957                         try {
   17958                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   17959                                     "Trimming memory of ui hidden " + app.processName
   17960                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   17961                             app.thread.scheduleTrimMemory(
   17962                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   17963                         } catch (RemoteException e) {
   17964                         }
   17965                     }
   17966                     app.pendingUiClean = false;
   17967                 }
   17968                 app.trimMemoryLevel = 0;
   17969             }
   17970         }
   17971 
   17972         if (mAlwaysFinishActivities) {
   17973             // Need to do this on its own message because the stack may not
   17974             // be in a consistent state at this point.
   17975             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   17976         }
   17977 
   17978         if (allChanged) {
   17979             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   17980         }
   17981 
   17982         if (mProcessStats.shouldWriteNowLocked(now)) {
   17983             mHandler.post(new Runnable() {
   17984                 @Override public void run() {
   17985                     synchronized (ActivityManagerService.this) {
   17986                         mProcessStats.writeStateAsyncLocked();
   17987                     }
   17988                 }
   17989             });
   17990         }
   17991 
   17992         if (DEBUG_OOM_ADJ) {
   17993             if (false) {
   17994                 RuntimeException here = new RuntimeException("here");
   17995                 here.fillInStackTrace();
   17996                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
   17997             } else {
   17998                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   17999             }
   18000         }
   18001     }
   18002 
   18003     final void trimApplications() {
   18004         synchronized (this) {
   18005             int i;
   18006 
   18007             // First remove any unused application processes whose package
   18008             // has been removed.
   18009             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   18010                 final ProcessRecord app = mRemovedProcesses.get(i);
   18011                 if (app.activities.size() == 0
   18012                         && app.curReceiver == null && app.services.size() == 0) {
   18013                     Slog.i(
   18014                         TAG, "Exiting empty application process "
   18015                         + app.processName + " ("
   18016                         + (app.thread != null ? app.thread.asBinder() : null)
   18017                         + ")\n");
   18018                     if (app.pid > 0 && app.pid != MY_PID) {
   18019                         app.kill("empty", false);
   18020                     } else {
   18021                         try {
   18022                             app.thread.scheduleExit();
   18023                         } catch (Exception e) {
   18024                             // Ignore exceptions.
   18025                         }
   18026                     }
   18027                     cleanUpApplicationRecordLocked(app, false, true, -1);
   18028                     mRemovedProcesses.remove(i);
   18029 
   18030                     if (app.persistent) {
   18031                         addAppLocked(app.info, false, null /* ABI override */);
   18032                     }
   18033                 }
   18034             }
   18035 
   18036             // Now update the oom adj for all processes.
   18037             updateOomAdjLocked();
   18038         }
   18039     }
   18040 
   18041     /** This method sends the specified signal to each of the persistent apps */
   18042     public void signalPersistentProcesses(int sig) throws RemoteException {
   18043         if (sig != Process.SIGNAL_USR1) {
   18044             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   18045         }
   18046 
   18047         synchronized (this) {
   18048             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   18049                     != PackageManager.PERMISSION_GRANTED) {
   18050                 throw new SecurityException("Requires permission "
   18051                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   18052             }
   18053 
   18054             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   18055                 ProcessRecord r = mLruProcesses.get(i);
   18056                 if (r.thread != null && r.persistent) {
   18057                     Process.sendSignal(r.pid, sig);
   18058                 }
   18059             }
   18060         }
   18061     }
   18062 
   18063     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
   18064         if (proc == null || proc == mProfileProc) {
   18065             proc = mProfileProc;
   18066             profileType = mProfileType;
   18067             clearProfilerLocked();
   18068         }
   18069         if (proc == null) {
   18070             return;
   18071         }
   18072         try {
   18073             proc.thread.profilerControl(false, null, profileType);
   18074         } catch (RemoteException e) {
   18075             throw new IllegalStateException("Process disappeared");
   18076         }
   18077     }
   18078 
   18079     private void clearProfilerLocked() {
   18080         if (mProfileFd != null) {
   18081             try {
   18082                 mProfileFd.close();
   18083             } catch (IOException e) {
   18084             }
   18085         }
   18086         mProfileApp = null;
   18087         mProfileProc = null;
   18088         mProfileFile = null;
   18089         mProfileType = 0;
   18090         mAutoStopProfiler = false;
   18091         mSamplingInterval = 0;
   18092     }
   18093 
   18094     public boolean profileControl(String process, int userId, boolean start,
   18095             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
   18096 
   18097         try {
   18098             synchronized (this) {
   18099                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18100                 // its own permission.
   18101                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18102                         != PackageManager.PERMISSION_GRANTED) {
   18103                     throw new SecurityException("Requires permission "
   18104                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18105                 }
   18106 
   18107                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
   18108                     throw new IllegalArgumentException("null profile info or fd");
   18109                 }
   18110 
   18111                 ProcessRecord proc = null;
   18112                 if (process != null) {
   18113                     proc = findProcessLocked(process, userId, "profileControl");
   18114                 }
   18115 
   18116                 if (start && (proc == null || proc.thread == null)) {
   18117                     throw new IllegalArgumentException("Unknown process: " + process);
   18118                 }
   18119 
   18120                 if (start) {
   18121                     stopProfilerLocked(null, 0);
   18122                     setProfileApp(proc.info, proc.processName, profilerInfo);
   18123                     mProfileProc = proc;
   18124                     mProfileType = profileType;
   18125                     ParcelFileDescriptor fd = profilerInfo.profileFd;
   18126                     try {
   18127                         fd = fd.dup();
   18128                     } catch (IOException e) {
   18129                         fd = null;
   18130                     }
   18131                     profilerInfo.profileFd = fd;
   18132                     proc.thread.profilerControl(start, profilerInfo, profileType);
   18133                     fd = null;
   18134                     mProfileFd = null;
   18135                 } else {
   18136                     stopProfilerLocked(proc, profileType);
   18137                     if (profilerInfo != null && profilerInfo.profileFd != null) {
   18138                         try {
   18139                             profilerInfo.profileFd.close();
   18140                         } catch (IOException e) {
   18141                         }
   18142                     }
   18143                 }
   18144 
   18145                 return true;
   18146             }
   18147         } catch (RemoteException e) {
   18148             throw new IllegalStateException("Process disappeared");
   18149         } finally {
   18150             if (profilerInfo != null && profilerInfo.profileFd != null) {
   18151                 try {
   18152                     profilerInfo.profileFd.close();
   18153                 } catch (IOException e) {
   18154                 }
   18155             }
   18156         }
   18157     }
   18158 
   18159     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   18160         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   18161                 userId, true, ALLOW_FULL_ONLY, callName, null);
   18162         ProcessRecord proc = null;
   18163         try {
   18164             int pid = Integer.parseInt(process);
   18165             synchronized (mPidsSelfLocked) {
   18166                 proc = mPidsSelfLocked.get(pid);
   18167             }
   18168         } catch (NumberFormatException e) {
   18169         }
   18170 
   18171         if (proc == null) {
   18172             ArrayMap<String, SparseArray<ProcessRecord>> all
   18173                     = mProcessNames.getMap();
   18174             SparseArray<ProcessRecord> procs = all.get(process);
   18175             if (procs != null && procs.size() > 0) {
   18176                 proc = procs.valueAt(0);
   18177                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   18178                     for (int i=1; i<procs.size(); i++) {
   18179                         ProcessRecord thisProc = procs.valueAt(i);
   18180                         if (thisProc.userId == userId) {
   18181                             proc = thisProc;
   18182                             break;
   18183                         }
   18184                     }
   18185                 }
   18186             }
   18187         }
   18188 
   18189         return proc;
   18190     }
   18191 
   18192     public boolean dumpHeap(String process, int userId, boolean managed,
   18193             String path, ParcelFileDescriptor fd) throws RemoteException {
   18194 
   18195         try {
   18196             synchronized (this) {
   18197                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   18198                 // its own permission (same as profileControl).
   18199                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   18200                         != PackageManager.PERMISSION_GRANTED) {
   18201                     throw new SecurityException("Requires permission "
   18202                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   18203                 }
   18204 
   18205                 if (fd == null) {
   18206                     throw new IllegalArgumentException("null fd");
   18207                 }
   18208 
   18209                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   18210                 if (proc == null || proc.thread == null) {
   18211                     throw new IllegalArgumentException("Unknown process: " + process);
   18212                 }
   18213 
   18214                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   18215                 if (!isDebuggable) {
   18216                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   18217                         throw new SecurityException("Process not debuggable: " + proc);
   18218                     }
   18219                 }
   18220 
   18221                 proc.thread.dumpHeap(managed, path, fd);
   18222                 fd = null;
   18223                 return true;
   18224             }
   18225         } catch (RemoteException e) {
   18226             throw new IllegalStateException("Process disappeared");
   18227         } finally {
   18228             if (fd != null) {
   18229                 try {
   18230                     fd.close();
   18231                 } catch (IOException e) {
   18232                 }
   18233             }
   18234         }
   18235     }
   18236 
   18237     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   18238     public void monitor() {
   18239         synchronized (this) { }
   18240     }
   18241 
   18242     void onCoreSettingsChange(Bundle settings) {
   18243         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   18244             ProcessRecord processRecord = mLruProcesses.get(i);
   18245             try {
   18246                 if (processRecord.thread != null) {
   18247                     processRecord.thread.setCoreSettings(settings);
   18248                 }
   18249             } catch (RemoteException re) {
   18250                 /* ignore */
   18251             }
   18252         }
   18253     }
   18254 
   18255     // Multi-user methods
   18256 
   18257     /**
   18258      * Start user, if its not already running, but don't bring it to foreground.
   18259      */
   18260     @Override
   18261     public boolean startUserInBackground(final int userId) {
   18262         return startUser(userId, /* foreground */ false);
   18263     }
   18264 
   18265     /**
   18266      * Start user, if its not already running, and bring it to foreground.
   18267      */
   18268     boolean startUserInForeground(final int userId, Dialog dlg) {
   18269         boolean result = startUser(userId, /* foreground */ true);
   18270         dlg.dismiss();
   18271         return result;
   18272     }
   18273 
   18274     /**
   18275      * Refreshes the list of users related to the current user when either a
   18276      * user switch happens or when a new related user is started in the
   18277      * background.
   18278      */
   18279     private void updateCurrentProfileIdsLocked() {
   18280         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18281                 mCurrentUserId, false /* enabledOnly */);
   18282         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
   18283         for (int i = 0; i < currentProfileIds.length; i++) {
   18284             currentProfileIds[i] = profiles.get(i).id;
   18285         }
   18286         mCurrentProfileIds = currentProfileIds;
   18287 
   18288         synchronized (mUserProfileGroupIdsSelfLocked) {
   18289             mUserProfileGroupIdsSelfLocked.clear();
   18290             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
   18291             for (int i = 0; i < users.size(); i++) {
   18292                 UserInfo user = users.get(i);
   18293                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
   18294                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
   18295                 }
   18296             }
   18297         }
   18298     }
   18299 
   18300     private Set getProfileIdsLocked(int userId) {
   18301         Set userIds = new HashSet<Integer>();
   18302         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18303                 userId, false /* enabledOnly */);
   18304         for (UserInfo user : profiles) {
   18305             userIds.add(Integer.valueOf(user.id));
   18306         }
   18307         return userIds;
   18308     }
   18309 
   18310     @Override
   18311     public boolean switchUser(final int userId) {
   18312         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   18313         String userName;
   18314         synchronized (this) {
   18315             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18316             if (userInfo == null) {
   18317                 Slog.w(TAG, "No user info for user #" + userId);
   18318                 return false;
   18319             }
   18320             if (userInfo.isManagedProfile()) {
   18321                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18322                 return false;
   18323             }
   18324             userName = userInfo.name;
   18325             mTargetUserId = userId;
   18326         }
   18327         mHandler.removeMessages(START_USER_SWITCH_MSG);
   18328         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
   18329         return true;
   18330     }
   18331 
   18332     private void showUserSwitchDialog(int userId, String userName) {
   18333         // The dialog will show and then initiate the user switch by calling startUserInForeground
   18334         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
   18335                 true /* above system */);
   18336         d.show();
   18337     }
   18338 
   18339     private boolean startUser(final int userId, final boolean foreground) {
   18340         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18341                 != PackageManager.PERMISSION_GRANTED) {
   18342             String msg = "Permission Denial: switchUser() from pid="
   18343                     + Binder.getCallingPid()
   18344                     + ", uid=" + Binder.getCallingUid()
   18345                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   18346             Slog.w(TAG, msg);
   18347             throw new SecurityException(msg);
   18348         }
   18349 
   18350         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
   18351 
   18352         final long ident = Binder.clearCallingIdentity();
   18353         try {
   18354             synchronized (this) {
   18355                 final int oldUserId = mCurrentUserId;
   18356                 if (oldUserId == userId) {
   18357                     return true;
   18358                 }
   18359 
   18360                 mStackSupervisor.setLockTaskModeLocked(null, false);
   18361 
   18362                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   18363                 if (userInfo == null) {
   18364                     Slog.w(TAG, "No user info for user #" + userId);
   18365                     return false;
   18366                 }
   18367                 if (foreground && userInfo.isManagedProfile()) {
   18368                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
   18369                     return false;
   18370                 }
   18371 
   18372                 if (foreground) {
   18373                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   18374                             R.anim.screen_user_enter);
   18375                 }
   18376 
   18377                 boolean needStart = false;
   18378 
   18379                 // If the user we are switching to is not currently started, then
   18380                 // we need to start it now.
   18381                 if (mStartedUsers.get(userId) == null) {
   18382                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   18383                     updateStartedUserArrayLocked();
   18384                     needStart = true;
   18385                 }
   18386 
   18387                 final Integer userIdInt = Integer.valueOf(userId);
   18388                 mUserLru.remove(userIdInt);
   18389                 mUserLru.add(userIdInt);
   18390 
   18391                 if (foreground) {
   18392                     mCurrentUserId = userId;
   18393                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
   18394                     updateCurrentProfileIdsLocked();
   18395                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
   18396                     // Once the internal notion of the active user has switched, we lock the device
   18397                     // with the option to show the user switcher on the keyguard.
   18398                     mWindowManager.lockNow(null);
   18399                 } else {
   18400                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
   18401                     updateCurrentProfileIdsLocked();
   18402                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
   18403                     mUserLru.remove(currentUserIdInt);
   18404                     mUserLru.add(currentUserIdInt);
   18405                 }
   18406 
   18407                 final UserStartedState uss = mStartedUsers.get(userId);
   18408 
   18409                 // Make sure user is in the started state.  If it is currently
   18410                 // stopping, we need to knock that off.
   18411                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   18412                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   18413                     // so we can just fairly silently bring the user back from
   18414                     // the almost-dead.
   18415                     uss.mState = UserStartedState.STATE_RUNNING;
   18416                     updateStartedUserArrayLocked();
   18417                     needStart = true;
   18418                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   18419                     // This means ACTION_SHUTDOWN has been sent, so we will
   18420                     // need to treat this as a new boot of the user.
   18421                     uss.mState = UserStartedState.STATE_BOOTING;
   18422                     updateStartedUserArrayLocked();
   18423                     needStart = true;
   18424                 }
   18425 
   18426                 if (uss.mState == UserStartedState.STATE_BOOTING) {
   18427                     // Booting up a new user, need to tell system services about it.
   18428                     // Note that this is on the same handler as scheduling of broadcasts,
   18429                     // which is important because it needs to go first.
   18430                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
   18431                 }
   18432 
   18433                 if (foreground) {
   18434                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
   18435                             oldUserId));
   18436                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   18437                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   18438                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   18439                             oldUserId, userId, uss));
   18440                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   18441                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   18442                 }
   18443 
   18444                 if (needStart) {
   18445                     // Send USER_STARTED broadcast
   18446                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   18447                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18448                             | Intent.FLAG_RECEIVER_FOREGROUND);
   18449                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18450                     broadcastIntentLocked(null, null, intent,
   18451                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18452                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   18453                 }
   18454 
   18455                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   18456                     if (userId != UserHandle.USER_OWNER) {
   18457                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   18458                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   18459                         broadcastIntentLocked(null, null, intent, null,
   18460                                 new IIntentReceiver.Stub() {
   18461                                     public void performReceive(Intent intent, int resultCode,
   18462                                             String data, Bundle extras, boolean ordered,
   18463                                             boolean sticky, int sendingUser) {
   18464                                         onUserInitialized(uss, foreground, oldUserId, userId);
   18465                                     }
   18466                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   18467                                 true, false, MY_PID, Process.SYSTEM_UID,
   18468                                 userId);
   18469                         uss.initializing = true;
   18470                     } else {
   18471                         getUserManagerLocked().makeInitialized(userInfo.id);
   18472                     }
   18473                 }
   18474 
   18475                 if (foreground) {
   18476                     if (!uss.initializing) {
   18477                         moveUserToForeground(uss, oldUserId, userId);
   18478                     }
   18479                 } else {
   18480                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
   18481                 }
   18482 
   18483                 if (needStart) {
   18484                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   18485                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   18486                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18487                     broadcastIntentLocked(null, null, intent,
   18488                             null, new IIntentReceiver.Stub() {
   18489                                 @Override
   18490                                 public void performReceive(Intent intent, int resultCode, String data,
   18491                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   18492                                         throws RemoteException {
   18493                                 }
   18494                             }, 0, null, null,
   18495                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   18496                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   18497                 }
   18498             }
   18499         } finally {
   18500             Binder.restoreCallingIdentity(ident);
   18501         }
   18502 
   18503         return true;
   18504     }
   18505 
   18506     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   18507         long ident = Binder.clearCallingIdentity();
   18508         try {
   18509             Intent intent;
   18510             if (oldUserId >= 0) {
   18511                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
   18512                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
   18513                 int count = profiles.size();
   18514                 for (int i = 0; i < count; i++) {
   18515                     int profileUserId = profiles.get(i).id;
   18516                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   18517                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18518                             | Intent.FLAG_RECEIVER_FOREGROUND);
   18519                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   18520                     broadcastIntentLocked(null, null, intent,
   18521                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18522                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   18523                 }
   18524             }
   18525             if (newUserId >= 0) {
   18526                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
   18527                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
   18528                 int count = profiles.size();
   18529                 for (int i = 0; i < count; i++) {
   18530                     int profileUserId = profiles.get(i).id;
   18531                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   18532                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18533                             | Intent.FLAG_RECEIVER_FOREGROUND);
   18534                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
   18535                     broadcastIntentLocked(null, null, intent,
   18536                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   18537                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
   18538                 }
   18539                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   18540                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   18541                         | Intent.FLAG_RECEIVER_FOREGROUND);
   18542                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   18543                 broadcastIntentLocked(null, null, intent,
   18544                         null, null, 0, null, null,
   18545                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   18546                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   18547             }
   18548         } finally {
   18549             Binder.restoreCallingIdentity(ident);
   18550         }
   18551     }
   18552 
   18553     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   18554             final int newUserId) {
   18555         final int N = mUserSwitchObservers.beginBroadcast();
   18556         if (N > 0) {
   18557             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   18558                 int mCount = 0;
   18559                 @Override
   18560                 public void sendResult(Bundle data) throws RemoteException {
   18561                     synchronized (ActivityManagerService.this) {
   18562                         if (mCurUserSwitchCallback == this) {
   18563                             mCount++;
   18564                             if (mCount == N) {
   18565                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   18566                             }
   18567                         }
   18568                     }
   18569                 }
   18570             };
   18571             synchronized (this) {
   18572                 uss.switching = true;
   18573                 mCurUserSwitchCallback = callback;
   18574             }
   18575             for (int i=0; i<N; i++) {
   18576                 try {
   18577                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   18578                             newUserId, callback);
   18579                 } catch (RemoteException e) {
   18580                 }
   18581             }
   18582         } else {
   18583             synchronized (this) {
   18584                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   18585             }
   18586         }
   18587         mUserSwitchObservers.finishBroadcast();
   18588     }
   18589 
   18590     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   18591         synchronized (this) {
   18592             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   18593             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   18594         }
   18595     }
   18596 
   18597     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   18598         mCurUserSwitchCallback = null;
   18599         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   18600         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   18601                 oldUserId, newUserId, uss));
   18602     }
   18603 
   18604     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
   18605         synchronized (this) {
   18606             if (foreground) {
   18607                 moveUserToForeground(uss, oldUserId, newUserId);
   18608             }
   18609         }
   18610 
   18611         completeSwitchAndInitalize(uss, newUserId, true, false);
   18612     }
   18613 
   18614     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
   18615         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
   18616         if (homeInFront) {
   18617             startHomeActivityLocked(newUserId);
   18618         } else {
   18619             mStackSupervisor.resumeTopActivitiesLocked();
   18620         }
   18621         EventLogTags.writeAmSwitchUser(newUserId);
   18622         getUserManagerLocked().userForeground(newUserId);
   18623         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
   18624     }
   18625 
   18626     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   18627         completeSwitchAndInitalize(uss, newUserId, false, true);
   18628     }
   18629 
   18630     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   18631             boolean clearInitializing, boolean clearSwitching) {
   18632         boolean unfrozen = false;
   18633         synchronized (this) {
   18634             if (clearInitializing) {
   18635                 uss.initializing = false;
   18636                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   18637             }
   18638             if (clearSwitching) {
   18639                 uss.switching = false;
   18640             }
   18641             if (!uss.switching && !uss.initializing) {
   18642                 mWindowManager.stopFreezingScreen();
   18643                 unfrozen = true;
   18644             }
   18645         }
   18646         if (unfrozen) {
   18647             final int N = mUserSwitchObservers.beginBroadcast();
   18648             for (int i=0; i<N; i++) {
   18649                 try {
   18650                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   18651                 } catch (RemoteException e) {
   18652                 }
   18653             }
   18654             mUserSwitchObservers.finishBroadcast();
   18655         }
   18656     }
   18657 
   18658     void scheduleStartProfilesLocked() {
   18659         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
   18660             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
   18661                     DateUtils.SECOND_IN_MILLIS);
   18662         }
   18663     }
   18664 
   18665     void startProfilesLocked() {
   18666         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
   18667         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
   18668                 mCurrentUserId, false /* enabledOnly */);
   18669         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
   18670         for (UserInfo user : profiles) {
   18671             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
   18672                     && user.id != mCurrentUserId) {
   18673                 toStart.add(user);
   18674             }
   18675         }
   18676         final int n = toStart.size();
   18677         int i = 0;
   18678         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
   18679             startUserInBackground(toStart.get(i).id);
   18680         }
   18681         if (i < n) {
   18682             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
   18683         }
   18684     }
   18685 
   18686     void finishUserBoot(UserStartedState uss) {
   18687         synchronized (this) {
   18688             if (uss.mState == UserStartedState.STATE_BOOTING
   18689                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   18690                 uss.mState = UserStartedState.STATE_RUNNING;
   18691                 final int userId = uss.mHandle.getIdentifier();
   18692                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   18693                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18694                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   18695                 broadcastIntentLocked(null, null, intent,
   18696                         null, null, 0, null, null,
   18697                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   18698                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   18699             }
   18700         }
   18701     }
   18702 
   18703     void finishUserSwitch(UserStartedState uss) {
   18704         synchronized (this) {
   18705             finishUserBoot(uss);
   18706 
   18707             startProfilesLocked();
   18708 
   18709             int num = mUserLru.size();
   18710             int i = 0;
   18711             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   18712                 Integer oldUserId = mUserLru.get(i);
   18713                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   18714                 if (oldUss == null) {
   18715                     // Shouldn't happen, but be sane if it does.
   18716                     mUserLru.remove(i);
   18717                     num--;
   18718                     continue;
   18719                 }
   18720                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   18721                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   18722                     // This user is already stopping, doesn't count.
   18723                     num--;
   18724                     i++;
   18725                     continue;
   18726                 }
   18727                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   18728                     // Owner and current can't be stopped, but count as running.
   18729                     i++;
   18730                     continue;
   18731                 }
   18732                 // This is a user to be stopped.
   18733                 stopUserLocked(oldUserId, null);
   18734                 num--;
   18735                 i++;
   18736             }
   18737         }
   18738     }
   18739 
   18740     @Override
   18741     public int stopUser(final int userId, final IStopUserCallback callback) {
   18742         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18743                 != PackageManager.PERMISSION_GRANTED) {
   18744             String msg = "Permission Denial: switchUser() from pid="
   18745                     + Binder.getCallingPid()
   18746                     + ", uid=" + Binder.getCallingUid()
   18747                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   18748             Slog.w(TAG, msg);
   18749             throw new SecurityException(msg);
   18750         }
   18751         if (userId <= 0) {
   18752             throw new IllegalArgumentException("Can't stop primary user " + userId);
   18753         }
   18754         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
   18755         synchronized (this) {
   18756             return stopUserLocked(userId, callback);
   18757         }
   18758     }
   18759 
   18760     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   18761         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
   18762         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
   18763             return ActivityManager.USER_OP_IS_CURRENT;
   18764         }
   18765 
   18766         final UserStartedState uss = mStartedUsers.get(userId);
   18767         if (uss == null) {
   18768             // User is not started, nothing to do...  but we do need to
   18769             // callback if requested.
   18770             if (callback != null) {
   18771                 mHandler.post(new Runnable() {
   18772                     @Override
   18773                     public void run() {
   18774                         try {
   18775                             callback.userStopped(userId);
   18776                         } catch (RemoteException e) {
   18777                         }
   18778                     }
   18779                 });
   18780             }
   18781             return ActivityManager.USER_OP_SUCCESS;
   18782         }
   18783 
   18784         if (callback != null) {
   18785             uss.mStopCallbacks.add(callback);
   18786         }
   18787 
   18788         if (uss.mState != UserStartedState.STATE_STOPPING
   18789                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   18790             uss.mState = UserStartedState.STATE_STOPPING;
   18791             updateStartedUserArrayLocked();
   18792 
   18793             long ident = Binder.clearCallingIdentity();
   18794             try {
   18795                 // We are going to broadcast ACTION_USER_STOPPING and then
   18796                 // once that is done send a final ACTION_SHUTDOWN and then
   18797                 // stop the user.
   18798                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   18799                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   18800                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   18801                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   18802                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   18803                 // This is the result receiver for the final shutdown broadcast.
   18804                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   18805                     @Override
   18806                     public void performReceive(Intent intent, int resultCode, String data,
   18807                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   18808                         finishUserStop(uss);
   18809                     }
   18810                 };
   18811                 // This is the result receiver for the initial stopping broadcast.
   18812                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   18813                     @Override
   18814                     public void performReceive(Intent intent, int resultCode, String data,
   18815                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   18816                         // On to the next.
   18817                         synchronized (ActivityManagerService.this) {
   18818                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   18819                                 // Whoops, we are being started back up.  Abort, abort!
   18820                                 return;
   18821                             }
   18822                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   18823                         }
   18824                         mBatteryStatsService.noteEvent(
   18825                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
   18826                                 Integer.toString(userId), userId);
   18827                         mSystemServiceManager.stopUser(userId);
   18828                         broadcastIntentLocked(null, null, shutdownIntent,
   18829                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   18830                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   18831                     }
   18832                 };
   18833                 // Kick things off.
   18834                 broadcastIntentLocked(null, null, stoppingIntent,
   18835                         null, stoppingReceiver, 0, null, null,
   18836                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   18837                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   18838             } finally {
   18839                 Binder.restoreCallingIdentity(ident);
   18840             }
   18841         }
   18842 
   18843         return ActivityManager.USER_OP_SUCCESS;
   18844     }
   18845 
   18846     void finishUserStop(UserStartedState uss) {
   18847         final int userId = uss.mHandle.getIdentifier();
   18848         boolean stopped;
   18849         ArrayList<IStopUserCallback> callbacks;
   18850         synchronized (this) {
   18851             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   18852             if (mStartedUsers.get(userId) != uss) {
   18853                 stopped = false;
   18854             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   18855                 stopped = false;
   18856             } else {
   18857                 stopped = true;
   18858                 // User can no longer run.
   18859                 mStartedUsers.remove(userId);
   18860                 mUserLru.remove(Integer.valueOf(userId));
   18861                 updateStartedUserArrayLocked();
   18862 
   18863                 // Clean up all state and processes associated with the user.
   18864                 // Kill all the processes for the user.
   18865                 forceStopUserLocked(userId, "finish user");
   18866             }
   18867 
   18868             // Explicitly remove the old information in mRecentTasks.
   18869             removeRecentTasksForUserLocked(userId);
   18870         }
   18871 
   18872         for (int i=0; i<callbacks.size(); i++) {
   18873             try {
   18874                 if (stopped) callbacks.get(i).userStopped(userId);
   18875                 else callbacks.get(i).userStopAborted(userId);
   18876             } catch (RemoteException e) {
   18877             }
   18878         }
   18879 
   18880         if (stopped) {
   18881             mSystemServiceManager.cleanupUser(userId);
   18882             synchronized (this) {
   18883                 mStackSupervisor.removeUserLocked(userId);
   18884             }
   18885         }
   18886     }
   18887 
   18888     @Override
   18889     public UserInfo getCurrentUser() {
   18890         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
   18891                 != PackageManager.PERMISSION_GRANTED) && (
   18892                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18893                 != PackageManager.PERMISSION_GRANTED)) {
   18894             String msg = "Permission Denial: getCurrentUser() from pid="
   18895                     + Binder.getCallingPid()
   18896                     + ", uid=" + Binder.getCallingUid()
   18897                     + " requires " + INTERACT_ACROSS_USERS;
   18898             Slog.w(TAG, msg);
   18899             throw new SecurityException(msg);
   18900         }
   18901         synchronized (this) {
   18902             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   18903             return getUserManagerLocked().getUserInfo(userId);
   18904         }
   18905     }
   18906 
   18907     int getCurrentUserIdLocked() {
   18908         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
   18909     }
   18910 
   18911     @Override
   18912     public boolean isUserRunning(int userId, boolean orStopped) {
   18913         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   18914                 != PackageManager.PERMISSION_GRANTED) {
   18915             String msg = "Permission Denial: isUserRunning() from pid="
   18916                     + Binder.getCallingPid()
   18917                     + ", uid=" + Binder.getCallingUid()
   18918                     + " requires " + INTERACT_ACROSS_USERS;
   18919             Slog.w(TAG, msg);
   18920             throw new SecurityException(msg);
   18921         }
   18922         synchronized (this) {
   18923             return isUserRunningLocked(userId, orStopped);
   18924         }
   18925     }
   18926 
   18927     boolean isUserRunningLocked(int userId, boolean orStopped) {
   18928         UserStartedState state = mStartedUsers.get(userId);
   18929         if (state == null) {
   18930             return false;
   18931         }
   18932         if (orStopped) {
   18933             return true;
   18934         }
   18935         return state.mState != UserStartedState.STATE_STOPPING
   18936                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   18937     }
   18938 
   18939     @Override
   18940     public int[] getRunningUserIds() {
   18941         if (checkCallingPermission(INTERACT_ACROSS_USERS)
   18942                 != PackageManager.PERMISSION_GRANTED) {
   18943             String msg = "Permission Denial: isUserRunning() from pid="
   18944                     + Binder.getCallingPid()
   18945                     + ", uid=" + Binder.getCallingUid()
   18946                     + " requires " + INTERACT_ACROSS_USERS;
   18947             Slog.w(TAG, msg);
   18948             throw new SecurityException(msg);
   18949         }
   18950         synchronized (this) {
   18951             return mStartedUserArray;
   18952         }
   18953     }
   18954 
   18955     private void updateStartedUserArrayLocked() {
   18956         int num = 0;
   18957         for (int i=0; i<mStartedUsers.size();  i++) {
   18958             UserStartedState uss = mStartedUsers.valueAt(i);
   18959             // This list does not include stopping users.
   18960             if (uss.mState != UserStartedState.STATE_STOPPING
   18961                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   18962                 num++;
   18963             }
   18964         }
   18965         mStartedUserArray = new int[num];
   18966         num = 0;
   18967         for (int i=0; i<mStartedUsers.size();  i++) {
   18968             UserStartedState uss = mStartedUsers.valueAt(i);
   18969             if (uss.mState != UserStartedState.STATE_STOPPING
   18970                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   18971                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   18972                 num++;
   18973             }
   18974         }
   18975     }
   18976 
   18977     @Override
   18978     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   18979         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
   18980                 != PackageManager.PERMISSION_GRANTED) {
   18981             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   18982                     + Binder.getCallingPid()
   18983                     + ", uid=" + Binder.getCallingUid()
   18984                     + " requires " + INTERACT_ACROSS_USERS_FULL;
   18985             Slog.w(TAG, msg);
   18986             throw new SecurityException(msg);
   18987         }
   18988 
   18989         mUserSwitchObservers.register(observer);
   18990     }
   18991 
   18992     @Override
   18993     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   18994         mUserSwitchObservers.unregister(observer);
   18995     }
   18996 
   18997     private boolean userExists(int userId) {
   18998         if (userId == 0) {
   18999             return true;
   19000         }
   19001         UserManagerService ums = getUserManagerLocked();
   19002         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   19003     }
   19004 
   19005     int[] getUsersLocked() {
   19006         UserManagerService ums = getUserManagerLocked();
   19007         return ums != null ? ums.getUserIds() : new int[] { 0 };
   19008     }
   19009 
   19010     UserManagerService getUserManagerLocked() {
   19011         if (mUserManager == null) {
   19012             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   19013             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   19014         }
   19015         return mUserManager;
   19016     }
   19017 
   19018     private int applyUserId(int uid, int userId) {
   19019         return UserHandle.getUid(userId, uid);
   19020     }
   19021 
   19022     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   19023         if (info == null) return null;
   19024         ApplicationInfo newInfo = new ApplicationInfo(info);
   19025         newInfo.uid = applyUserId(info.uid, userId);
   19026         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   19027                 + info.packageName;
   19028         return newInfo;
   19029     }
   19030 
   19031     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   19032         if (aInfo == null
   19033                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   19034             return aInfo;
   19035         }
   19036 
   19037         ActivityInfo info = new ActivityInfo(aInfo);
   19038         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   19039         return info;
   19040     }
   19041 
   19042     private final class LocalService extends ActivityManagerInternal {
   19043         @Override
   19044         public void goingToSleep() {
   19045             ActivityManagerService.this.goingToSleep();
   19046         }
   19047 
   19048         @Override
   19049         public void wakingUp() {
   19050             ActivityManagerService.this.wakingUp();
   19051         }
   19052 
   19053         @Override
   19054         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
   19055                 String processName, String abiOverride, int uid, Runnable crashHandler) {
   19056             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
   19057                     processName, abiOverride, uid, crashHandler);
   19058         }
   19059     }
   19060 
   19061     /**
   19062      * An implementation of IAppTask, that allows an app to manage its own tasks via
   19063      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
   19064      * only the process that calls getAppTasks() can call the AppTask methods.
   19065      */
   19066     class AppTaskImpl extends IAppTask.Stub {
   19067         private int mTaskId;
   19068         private int mCallingUid;
   19069 
   19070         public AppTaskImpl(int taskId, int callingUid) {
   19071             mTaskId = taskId;
   19072             mCallingUid = callingUid;
   19073         }
   19074 
   19075         private void checkCaller() {
   19076             if (mCallingUid != Binder.getCallingUid()) {
   19077                 throw new SecurityException("Caller " + mCallingUid
   19078                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
   19079             }
   19080         }
   19081 
   19082         @Override
   19083         public void finishAndRemoveTask() {
   19084             checkCaller();
   19085 
   19086             synchronized (ActivityManagerService.this) {
   19087                 long origId = Binder.clearCallingIdentity();
   19088                 try {
   19089                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19090                     if (tr == null) {
   19091                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19092                     }
   19093                     // Only kill the process if we are not a new document
   19094                     int flags = tr.getBaseIntent().getFlags();
   19095                     boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
   19096                             Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
   19097                     removeTaskByIdLocked(mTaskId,
   19098                             !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
   19099                 } finally {
   19100                     Binder.restoreCallingIdentity(origId);
   19101                 }
   19102             }
   19103         }
   19104 
   19105         @Override
   19106         public ActivityManager.RecentTaskInfo getTaskInfo() {
   19107             checkCaller();
   19108 
   19109             synchronized (ActivityManagerService.this) {
   19110                 long origId = Binder.clearCallingIdentity();
   19111                 try {
   19112                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19113                     if (tr == null) {
   19114                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19115                     }
   19116                     return createRecentTaskInfoFromTaskRecord(tr);
   19117                 } finally {
   19118                     Binder.restoreCallingIdentity(origId);
   19119                 }
   19120             }
   19121         }
   19122 
   19123         @Override
   19124         public void moveToFront() {
   19125             checkCaller();
   19126 
   19127             final TaskRecord tr;
   19128             synchronized (ActivityManagerService.this) {
   19129                 tr = recentTaskForIdLocked(mTaskId);
   19130                 if (tr == null) {
   19131                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19132                 }
   19133                 if (tr.getRootActivity() != null) {
   19134                     moveTaskToFrontLocked(tr.taskId, 0, null);
   19135                     return;
   19136                 }
   19137             }
   19138 
   19139             startActivityFromRecentsInner(tr.taskId, null);
   19140         }
   19141 
   19142         @Override
   19143         public int startActivity(IBinder whoThread, String callingPackage,
   19144                 Intent intent, String resolvedType, Bundle options) {
   19145             checkCaller();
   19146 
   19147             int callingUser = UserHandle.getCallingUserId();
   19148             TaskRecord tr;
   19149             IApplicationThread appThread;
   19150             synchronized (ActivityManagerService.this) {
   19151                 tr = recentTaskForIdLocked(mTaskId);
   19152                 if (tr == null) {
   19153                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19154                 }
   19155                 appThread = ApplicationThreadNative.asInterface(whoThread);
   19156                 if (appThread == null) {
   19157                     throw new IllegalArgumentException("Bad app thread " + appThread);
   19158                 }
   19159             }
   19160             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
   19161                     resolvedType, null, null, null, null, 0, 0, null, null,
   19162                     null, options, callingUser, null, tr);
   19163         }
   19164 
   19165         @Override
   19166         public void setExcludeFromRecents(boolean exclude) {
   19167             checkCaller();
   19168 
   19169             synchronized (ActivityManagerService.this) {
   19170                 long origId = Binder.clearCallingIdentity();
   19171                 try {
   19172                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
   19173                     if (tr == null) {
   19174                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
   19175                     }
   19176                     Intent intent = tr.getBaseIntent();
   19177                     if (exclude) {
   19178                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19179                     } else {
   19180                         intent.setFlags(intent.getFlags()
   19181                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
   19182                     }
   19183                 } finally {
   19184                     Binder.restoreCallingIdentity(origId);
   19185                 }
   19186             }
   19187         }
   19188     }
   19189 }
   19190