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.content.pm.PackageManager.PERMISSION_GRANTED;
     20 import static com.android.internal.util.XmlUtils.readIntAttribute;
     21 import static com.android.internal.util.XmlUtils.readLongAttribute;
     22 import static com.android.internal.util.XmlUtils.writeIntAttribute;
     23 import static com.android.internal.util.XmlUtils.writeLongAttribute;
     24 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     25 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     26 
     27 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
     28 
     29 import android.app.AppOpsManager;
     30 import android.appwidget.AppWidgetManager;
     31 import android.util.ArrayMap;
     32 import com.android.internal.R;
     33 import com.android.internal.annotations.GuardedBy;
     34 import com.android.internal.app.IAppOpsService;
     35 import com.android.internal.app.ProcessStats;
     36 import com.android.internal.app.ResolverActivity;
     37 import com.android.internal.os.BackgroundThread;
     38 import com.android.internal.os.BatteryStatsImpl;
     39 import com.android.internal.os.ProcessCpuTracker;
     40 import com.android.internal.os.TransferPipe;
     41 import com.android.internal.util.FastPrintWriter;
     42 import com.android.internal.util.FastXmlSerializer;
     43 import com.android.internal.util.MemInfoReader;
     44 import com.android.internal.util.Preconditions;
     45 import com.android.server.AppOpsService;
     46 import com.android.server.AttributeCache;
     47 import com.android.server.IntentResolver;
     48 import com.android.internal.app.ProcessMap;
     49 import com.android.server.SystemServer;
     50 import com.android.server.Watchdog;
     51 import com.android.server.am.ActivityStack.ActivityState;
     52 import com.android.server.firewall.IntentFirewall;
     53 import com.android.server.pm.UserManagerService;
     54 import com.android.server.wm.AppTransition;
     55 import com.android.server.wm.StackBox;
     56 import com.android.server.wm.WindowManagerService;
     57 import com.google.android.collect.Lists;
     58 import com.google.android.collect.Maps;
     59 
     60 import dalvik.system.Zygote;
     61 
     62 import libcore.io.IoUtils;
     63 
     64 import org.xmlpull.v1.XmlPullParser;
     65 import org.xmlpull.v1.XmlPullParserException;
     66 import org.xmlpull.v1.XmlSerializer;
     67 
     68 import android.app.Activity;
     69 import android.app.ActivityManager;
     70 import android.app.ActivityManager.RunningTaskInfo;
     71 import android.app.ActivityManager.StackBoxInfo;
     72 import android.app.ActivityManager.StackInfo;
     73 import android.app.ActivityManagerNative;
     74 import android.app.ActivityOptions;
     75 import android.app.ActivityThread;
     76 import android.app.AlertDialog;
     77 import android.app.AppGlobals;
     78 import android.app.ApplicationErrorReport;
     79 import android.app.Dialog;
     80 import android.app.IActivityController;
     81 import android.app.IApplicationThread;
     82 import android.app.IInstrumentationWatcher;
     83 import android.app.INotificationManager;
     84 import android.app.IProcessObserver;
     85 import android.app.IServiceConnection;
     86 import android.app.IStopUserCallback;
     87 import android.app.IThumbnailReceiver;
     88 import android.app.IUiAutomationConnection;
     89 import android.app.IUserSwitchObserver;
     90 import android.app.Instrumentation;
     91 import android.app.Notification;
     92 import android.app.NotificationManager;
     93 import android.app.PendingIntent;
     94 import android.app.backup.IBackupManager;
     95 import android.content.ActivityNotFoundException;
     96 import android.content.BroadcastReceiver;
     97 import android.content.ClipData;
     98 import android.content.ComponentCallbacks2;
     99 import android.content.ComponentName;
    100 import android.content.ContentProvider;
    101 import android.content.ContentResolver;
    102 import android.content.Context;
    103 import android.content.DialogInterface;
    104 import android.content.IContentProvider;
    105 import android.content.IIntentReceiver;
    106 import android.content.IIntentSender;
    107 import android.content.Intent;
    108 import android.content.IntentFilter;
    109 import android.content.IntentSender;
    110 import android.content.pm.ActivityInfo;
    111 import android.content.pm.ApplicationInfo;
    112 import android.content.pm.ConfigurationInfo;
    113 import android.content.pm.IPackageDataObserver;
    114 import android.content.pm.IPackageManager;
    115 import android.content.pm.InstrumentationInfo;
    116 import android.content.pm.PackageInfo;
    117 import android.content.pm.PackageManager;
    118 import android.content.pm.ParceledListSlice;
    119 import android.content.pm.UserInfo;
    120 import android.content.pm.PackageManager.NameNotFoundException;
    121 import android.content.pm.PathPermission;
    122 import android.content.pm.ProviderInfo;
    123 import android.content.pm.ResolveInfo;
    124 import android.content.pm.ServiceInfo;
    125 import android.content.res.CompatibilityInfo;
    126 import android.content.res.Configuration;
    127 import android.graphics.Bitmap;
    128 import android.net.Proxy;
    129 import android.net.ProxyProperties;
    130 import android.net.Uri;
    131 import android.os.Binder;
    132 import android.os.Build;
    133 import android.os.Bundle;
    134 import android.os.Debug;
    135 import android.os.DropBoxManager;
    136 import android.os.Environment;
    137 import android.os.FileObserver;
    138 import android.os.FileUtils;
    139 import android.os.Handler;
    140 import android.os.IBinder;
    141 import android.os.IPermissionController;
    142 import android.os.IRemoteCallback;
    143 import android.os.IUserManager;
    144 import android.os.Looper;
    145 import android.os.Message;
    146 import android.os.Parcel;
    147 import android.os.ParcelFileDescriptor;
    148 import android.os.Process;
    149 import android.os.RemoteCallbackList;
    150 import android.os.RemoteException;
    151 import android.os.SELinux;
    152 import android.os.ServiceManager;
    153 import android.os.StrictMode;
    154 import android.os.SystemClock;
    155 import android.os.SystemProperties;
    156 import android.os.UpdateLock;
    157 import android.os.UserHandle;
    158 import android.provider.Settings;
    159 import android.text.format.DateUtils;
    160 import android.text.format.Time;
    161 import android.util.AtomicFile;
    162 import android.util.EventLog;
    163 import android.util.Log;
    164 import android.util.Pair;
    165 import android.util.PrintWriterPrinter;
    166 import android.util.Slog;
    167 import android.util.SparseArray;
    168 import android.util.TimeUtils;
    169 import android.util.Xml;
    170 import android.view.Gravity;
    171 import android.view.LayoutInflater;
    172 import android.view.View;
    173 import android.view.WindowManager;
    174 
    175 import java.io.BufferedInputStream;
    176 import java.io.BufferedOutputStream;
    177 import java.io.DataInputStream;
    178 import java.io.DataOutputStream;
    179 import java.io.File;
    180 import java.io.FileDescriptor;
    181 import java.io.FileInputStream;
    182 import java.io.FileNotFoundException;
    183 import java.io.FileOutputStream;
    184 import java.io.IOException;
    185 import java.io.InputStreamReader;
    186 import java.io.PrintWriter;
    187 import java.io.StringWriter;
    188 import java.lang.ref.WeakReference;
    189 import java.util.ArrayList;
    190 import java.util.Arrays;
    191 import java.util.Collections;
    192 import java.util.Comparator;
    193 import java.util.HashMap;
    194 import java.util.HashSet;
    195 import java.util.Iterator;
    196 import java.util.List;
    197 import java.util.Locale;
    198 import java.util.Map;
    199 import java.util.Set;
    200 import java.util.concurrent.atomic.AtomicBoolean;
    201 import java.util.concurrent.atomic.AtomicLong;
    202 
    203 public final class ActivityManagerService extends ActivityManagerNative
    204         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    205     private static final String USER_DATA_DIR = "/data/user/";
    206     static final String TAG = "ActivityManager";
    207     static final String TAG_MU = "ActivityManagerServiceMU";
    208     static final boolean DEBUG = false;
    209     static final boolean localLOGV = DEBUG;
    210     static final boolean DEBUG_BACKUP = localLOGV || false;
    211     static final boolean DEBUG_BROADCAST = localLOGV || false;
    212     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
    213     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
    214     static final boolean DEBUG_CLEANUP = localLOGV || false;
    215     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
    216     static final boolean DEBUG_FOCUS = false;
    217     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
    218     static final boolean DEBUG_MU = localLOGV || false;
    219     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
    220     static final boolean DEBUG_PAUSE = localLOGV || false;
    221     static final boolean DEBUG_POWER = localLOGV || false;
    222     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    223     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    224     static final boolean DEBUG_PROCESSES = localLOGV || false;
    225     static final boolean DEBUG_PROVIDER = localLOGV || false;
    226     static final boolean DEBUG_RESULTS = localLOGV || false;
    227     static final boolean DEBUG_SERVICE = localLOGV || false;
    228     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    229     static final boolean DEBUG_STACK = localLOGV || false;
    230     static final boolean DEBUG_SWITCH = localLOGV || false;
    231     static final boolean DEBUG_TASKS = localLOGV || false;
    232     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    233     static final boolean DEBUG_TRANSITION = localLOGV || false;
    234     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    235     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    236     static final boolean DEBUG_VISBILITY = localLOGV || false;
    237     static final boolean DEBUG_PSS = localLOGV || false;
    238     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
    239     static final boolean VALIDATE_TOKENS = false;
    240     static final boolean SHOW_ACTIVITY_START_TIME = true;
    241 
    242     // Control over CPU and battery monitoring.
    243     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    244     static final boolean MONITOR_CPU_USAGE = true;
    245     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    246     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    247     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    248 
    249     // The flags that are set for all calls we make to the package manager.
    250     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    251 
    252     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    253 
    254     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    255 
    256     // Maximum number of recent tasks that we can remember.
    257     static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
    258 
    259     // Amount of time after a call to stopAppSwitches() during which we will
    260     // prevent further untrusted switches from happening.
    261     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    262 
    263     // How long we wait for a launched process to attach to the activity manager
    264     // before we decide it's never going to come up for real.
    265     static final int PROC_START_TIMEOUT = 10*1000;
    266 
    267     // How long we wait for a launched process to attach to the activity manager
    268     // before we decide it's never going to come up for real, when the process was
    269     // started with a wrapper for instrumentation (such as Valgrind) because it
    270     // could take much longer than usual.
    271     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    272 
    273     // How long to wait after going idle before forcing apps to GC.
    274     static final int GC_TIMEOUT = 5*1000;
    275 
    276     // The minimum amount of time between successive GC requests for a process.
    277     static final int GC_MIN_INTERVAL = 60*1000;
    278 
    279     // The minimum amount of time between successive PSS requests for a process.
    280     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    281 
    282     // The minimum amount of time between successive PSS requests for a process
    283     // when the request is due to the memory state being lowered.
    284     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    285 
    286     // The rate at which we check for apps using excessive power -- 15 mins.
    287     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    288 
    289     // The minimum sample duration we will allow before deciding we have
    290     // enough data on wake locks to start killing things.
    291     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    292 
    293     // The minimum sample duration we will allow before deciding we have
    294     // enough data on CPU usage to start killing things.
    295     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    296 
    297     // How long we allow a receiver to run before giving up on it.
    298     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    299     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    300 
    301     // How long we wait until we timeout on key dispatching.
    302     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    303 
    304     // How long we wait until we timeout on key dispatching during instrumentation.
    305     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    306 
    307     // Amount of time we wait for observers to handle a user switch before
    308     // giving up on them and unfreezing the screen.
    309     static final int USER_SWITCH_TIMEOUT = 2*1000;
    310 
    311     // Maximum number of users we allow to be running at a time.
    312     static final int MAX_RUNNING_USERS = 3;
    313 
    314     // How long to wait in getAssistContextExtras for the activity and foreground services
    315     // to respond with the result.
    316     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    317 
    318     // Maximum number of persisted Uri grants a package is allowed
    319     static final int MAX_PERSISTED_URI_GRANTS = 128;
    320 
    321     static final int MY_PID = Process.myPid();
    322 
    323     static final String[] EMPTY_STRING_ARRAY = new String[0];
    324 
    325     /** Run all ActivityStacks through this */
    326     ActivityStackSupervisor mStackSupervisor;
    327 
    328     public IntentFirewall mIntentFirewall;
    329 
    330     private final boolean mHeadless;
    331 
    332     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    333     // default actuion automatically.  Important for devices without direct input
    334     // devices.
    335     private boolean mShowDialogs = true;
    336 
    337     /**
    338      * Description of a request to start a new activity, which has been held
    339      * due to app switches being disabled.
    340      */
    341     static class PendingActivityLaunch {
    342         final ActivityRecord r;
    343         final ActivityRecord sourceRecord;
    344         final int startFlags;
    345         final ActivityStack stack;
    346 
    347         PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
    348                 int _startFlags, ActivityStack _stack) {
    349             r = _r;
    350             sourceRecord = _sourceRecord;
    351             startFlags = _startFlags;
    352             stack = _stack;
    353         }
    354     }
    355 
    356     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    357             = new ArrayList<PendingActivityLaunch>();
    358 
    359     BroadcastQueue mFgBroadcastQueue;
    360     BroadcastQueue mBgBroadcastQueue;
    361     // Convenient for easy iteration over the queues. Foreground is first
    362     // so that dispatch of foreground broadcasts gets precedence.
    363     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    364 
    365     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    366         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    367         if (DEBUG_BACKGROUND_BROADCAST) {
    368             Slog.i(TAG, "Broadcast intent " + intent + " on "
    369                     + (isFg ? "foreground" : "background")
    370                     + " queue");
    371         }
    372         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    373     }
    374 
    375     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    376         for (BroadcastQueue queue : mBroadcastQueues) {
    377             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    378             if (r != null) {
    379                 return r;
    380             }
    381         }
    382         return null;
    383     }
    384 
    385     /**
    386      * Activity we have told the window manager to have key focus.
    387      */
    388     ActivityRecord mFocusedActivity = null;
    389 
    390     /**
    391      * List of intents that were used to start the most recent tasks.
    392      */
    393     private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    394 
    395     public class PendingAssistExtras extends Binder implements Runnable {
    396         public final ActivityRecord activity;
    397         public boolean haveResult = false;
    398         public Bundle result = null;
    399         public PendingAssistExtras(ActivityRecord _activity) {
    400             activity = _activity;
    401         }
    402         @Override
    403         public void run() {
    404             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    405             synchronized (this) {
    406                 haveResult = true;
    407                 notifyAll();
    408             }
    409         }
    410     }
    411 
    412     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    413             = new ArrayList<PendingAssistExtras>();
    414 
    415     /**
    416      * Process management.
    417      */
    418     final ProcessList mProcessList = new ProcessList();
    419 
    420     /**
    421      * All of the applications we currently have running organized by name.
    422      * The keys are strings of the application package name (as
    423      * returned by the package manager), and the keys are ApplicationRecord
    424      * objects.
    425      */
    426     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    427 
    428     /**
    429      * Tracking long-term execution of processes to look for abuse and other
    430      * bad app behavior.
    431      */
    432     final ProcessStatsService mProcessStats;
    433 
    434     /**
    435      * The currently running isolated processes.
    436      */
    437     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    438 
    439     /**
    440      * Counter for assigning isolated process uids, to avoid frequently reusing the
    441      * same ones.
    442      */
    443     int mNextIsolatedProcessUid = 0;
    444 
    445     /**
    446      * The currently running heavy-weight process, if any.
    447      */
    448     ProcessRecord mHeavyWeightProcess = null;
    449 
    450     /**
    451      * The last time that various processes have crashed.
    452      */
    453     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    454 
    455     /**
    456      * Set of applications that we consider to be bad, and will reject
    457      * incoming broadcasts from (which the user has no control over).
    458      * Processes are added to this set when they have crashed twice within
    459      * a minimum amount of time; they are removed from it when they are
    460      * later restarted (hopefully due to some user action).  The value is the
    461      * time it was added to the list.
    462      */
    463     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
    464 
    465     /**
    466      * All of the processes we currently have running organized by pid.
    467      * The keys are the pid running the application.
    468      *
    469      * <p>NOTE: This object is protected by its own lock, NOT the global
    470      * activity manager lock!
    471      */
    472     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    473 
    474     /**
    475      * All of the processes that have been forced to be foreground.  The key
    476      * is the pid of the caller who requested it (we hold a death
    477      * link on it).
    478      */
    479     abstract class ForegroundToken implements IBinder.DeathRecipient {
    480         int pid;
    481         IBinder token;
    482     }
    483     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    484 
    485     /**
    486      * List of records for processes that someone had tried to start before the
    487      * system was ready.  We don't start them at that point, but ensure they
    488      * are started by the time booting is complete.
    489      */
    490     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    491 
    492     /**
    493      * List of persistent applications that are in the process
    494      * of being started.
    495      */
    496     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    497 
    498     /**
    499      * Processes that are being forcibly torn down.
    500      */
    501     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    502 
    503     /**
    504      * List of running applications, sorted by recent usage.
    505      * The first entry in the list is the least recently used.
    506      */
    507     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    508 
    509     /**
    510      * Where in mLruProcesses that the processes hosting activities start.
    511      */
    512     int mLruProcessActivityStart = 0;
    513 
    514     /**
    515      * Where in mLruProcesses that the processes hosting services start.
    516      * This is after (lower index) than mLruProcessesActivityStart.
    517      */
    518     int mLruProcessServiceStart = 0;
    519 
    520     /**
    521      * List of processes that should gc as soon as things are idle.
    522      */
    523     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    524 
    525     /**
    526      * Processes we want to collect PSS data from.
    527      */
    528     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    529 
    530     /**
    531      * Last time we requested PSS data of all processes.
    532      */
    533     long mLastFullPssTime = SystemClock.uptimeMillis();
    534 
    535     /**
    536      * This is the process holding what we currently consider to be
    537      * the "home" activity.
    538      */
    539     ProcessRecord mHomeProcess;
    540 
    541     /**
    542      * This is the process holding the activity the user last visited that
    543      * is in a different process from the one they are currently in.
    544      */
    545     ProcessRecord mPreviousProcess;
    546 
    547     /**
    548      * The time at which the previous process was last visible.
    549      */
    550     long mPreviousProcessVisibleTime;
    551 
    552     /**
    553      * Which uses have been started, so are allowed to run code.
    554      */
    555     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    556 
    557     /**
    558      * LRU list of history of current users.  Most recently current is at the end.
    559      */
    560     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    561 
    562     /**
    563      * Constant array of the users that are currently started.
    564      */
    565     int[] mStartedUserArray = new int[] { 0 };
    566 
    567     /**
    568      * Registered observers of the user switching mechanics.
    569      */
    570     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    571             = new RemoteCallbackList<IUserSwitchObserver>();
    572 
    573     /**
    574      * Currently active user switch.
    575      */
    576     Object mCurUserSwitchCallback;
    577 
    578     /**
    579      * Packages that the user has asked to have run in screen size
    580      * compatibility mode instead of filling the screen.
    581      */
    582     final CompatModePackages mCompatModePackages;
    583 
    584     /**
    585      * Set of IntentSenderRecord objects that are currently active.
    586      */
    587     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    588             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    589 
    590     /**
    591      * Fingerprints (hashCode()) of stack traces that we've
    592      * already logged DropBox entries for.  Guarded by itself.  If
    593      * something (rogue user app) forces this over
    594      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    595      */
    596     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    597     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    598 
    599     /**
    600      * Strict Mode background batched logging state.
    601      *
    602      * The string buffer is guarded by itself, and its lock is also
    603      * used to determine if another batched write is already
    604      * in-flight.
    605      */
    606     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    607 
    608     /**
    609      * Keeps track of all IIntentReceivers that have been registered for
    610      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    611      * a ReceiverList.
    612      */
    613     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
    614             new HashMap<IBinder, ReceiverList>();
    615 
    616     /**
    617      * Resolver for broadcast intents to registered receivers.
    618      * Holds BroadcastFilter (subclass of IntentFilter).
    619      */
    620     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    621             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    622         @Override
    623         protected boolean allowFilterResult(
    624                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    625             IBinder target = filter.receiverList.receiver.asBinder();
    626             for (int i=dest.size()-1; i>=0; i--) {
    627                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    628                     return false;
    629                 }
    630             }
    631             return true;
    632         }
    633 
    634         @Override
    635         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    636             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    637                     || userId == filter.owningUserId) {
    638                 return super.newResult(filter, match, userId);
    639             }
    640             return null;
    641         }
    642 
    643         @Override
    644         protected BroadcastFilter[] newArray(int size) {
    645             return new BroadcastFilter[size];
    646         }
    647 
    648         @Override
    649         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    650             return packageName.equals(filter.packageName);
    651         }
    652     };
    653 
    654     /**
    655      * State of all active sticky broadcasts per user.  Keys are the action of the
    656      * sticky Intent, values are an ArrayList of all broadcasted intents with
    657      * that action (which should usually be one).  The SparseArray is keyed
    658      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    659      * for stickies that are sent to all users.
    660      */
    661     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    662             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    663 
    664     final ActiveServices mServices;
    665 
    666     /**
    667      * Backup/restore process management
    668      */
    669     String mBackupAppName = null;
    670     BackupRecord mBackupTarget = null;
    671 
    672     /**
    673      * List of PendingThumbnailsRecord objects of clients who are still
    674      * waiting to receive all of the thumbnails for a task.
    675      */
    676     final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
    677             new ArrayList<PendingThumbnailsRecord>();
    678 
    679     final ProviderMap mProviderMap;
    680 
    681     /**
    682      * List of content providers who have clients waiting for them.  The
    683      * application is currently being launched and the provider will be
    684      * removed from this list once it is published.
    685      */
    686     final ArrayList<ContentProviderRecord> mLaunchingProviders
    687             = new ArrayList<ContentProviderRecord>();
    688 
    689     /**
    690      * File storing persisted {@link #mGrantedUriPermissions}.
    691      */
    692     private final AtomicFile mGrantFile;
    693 
    694     /** XML constants used in {@link #mGrantFile} */
    695     private static final String TAG_URI_GRANTS = "uri-grants";
    696     private static final String TAG_URI_GRANT = "uri-grant";
    697     private static final String ATTR_USER_HANDLE = "userHandle";
    698     private static final String ATTR_SOURCE_PKG = "sourcePkg";
    699     private static final String ATTR_TARGET_PKG = "targetPkg";
    700     private static final String ATTR_URI = "uri";
    701     private static final String ATTR_MODE_FLAGS = "modeFlags";
    702     private static final String ATTR_CREATED_TIME = "createdTime";
    703 
    704     /**
    705      * Global set of specific {@link Uri} permissions that have been granted.
    706      * This optimized lookup structure maps from {@link UriPermission#targetUid}
    707      * to {@link UriPermission#uri} to {@link UriPermission}.
    708      */
    709     @GuardedBy("this")
    710     private final SparseArray<ArrayMap<Uri, UriPermission>>
    711             mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
    712 
    713     CoreSettingsObserver mCoreSettingsObserver;
    714 
    715     /**
    716      * Thread-local storage used to carry caller permissions over through
    717      * indirect content-provider access.
    718      */
    719     private class Identity {
    720         public int pid;
    721         public int uid;
    722 
    723         Identity(int _pid, int _uid) {
    724             pid = _pid;
    725             uid = _uid;
    726         }
    727     }
    728 
    729     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    730 
    731     /**
    732      * All information we have collected about the runtime performance of
    733      * any user id that can impact battery performance.
    734      */
    735     final BatteryStatsService mBatteryStatsService;
    736 
    737     /**
    738      * Information about component usage
    739      */
    740     final UsageStatsService mUsageStatsService;
    741 
    742     /**
    743      * Information about and control over application operations
    744      */
    745     final AppOpsService mAppOpsService;
    746 
    747     /**
    748      * Current configuration information.  HistoryRecord objects are given
    749      * a reference to this object to indicate which configuration they are
    750      * currently running in, so this object must be kept immutable.
    751      */
    752     Configuration mConfiguration = new Configuration();
    753 
    754     /**
    755      * Current sequencing integer of the configuration, for skipping old
    756      * configurations.
    757      */
    758     int mConfigurationSeq = 0;
    759 
    760     /**
    761      * Hardware-reported OpenGLES version.
    762      */
    763     final int GL_ES_VERSION;
    764 
    765     /**
    766      * List of initialization arguments to pass to all processes when binding applications to them.
    767      * For example, references to the commonly used services.
    768      */
    769     HashMap<String, IBinder> mAppBindArgs;
    770 
    771     /**
    772      * Temporary to avoid allocations.  Protected by main lock.
    773      */
    774     final StringBuilder mStringBuilder = new StringBuilder(256);
    775 
    776     /**
    777      * Used to control how we initialize the service.
    778      */
    779     boolean mStartRunning = false;
    780     ComponentName mTopComponent;
    781     String mTopAction;
    782     String mTopData;
    783     boolean mProcessesReady = false;
    784     boolean mSystemReady = false;
    785     boolean mBooting = false;
    786     boolean mWaitingUpdate = false;
    787     boolean mDidUpdate = false;
    788     boolean mOnBattery = false;
    789     boolean mLaunchWarningShown = false;
    790 
    791     Context mContext;
    792 
    793     int mFactoryTest;
    794 
    795     boolean mCheckedForSetup;
    796 
    797     /**
    798      * The time at which we will allow normal application switches again,
    799      * after a call to {@link #stopAppSwitches()}.
    800      */
    801     long mAppSwitchesAllowedTime;
    802 
    803     /**
    804      * This is set to true after the first switch after mAppSwitchesAllowedTime
    805      * is set; any switches after that will clear the time.
    806      */
    807     boolean mDidAppSwitch;
    808 
    809     /**
    810      * Last time (in realtime) at which we checked for power usage.
    811      */
    812     long mLastPowerCheckRealtime;
    813 
    814     /**
    815      * Last time (in uptime) at which we checked for power usage.
    816      */
    817     long mLastPowerCheckUptime;
    818 
    819     /**
    820      * Set while we are wanting to sleep, to prevent any
    821      * activities from being started/resumed.
    822      */
    823     boolean mSleeping = false;
    824 
    825     /**
    826      * State of external calls telling us if the device is asleep.
    827      */
    828     boolean mWentToSleep = false;
    829 
    830     /**
    831      * State of external call telling us if the lock screen is shown.
    832      */
    833     boolean mLockScreenShown = false;
    834 
    835     /**
    836      * Set if we are shutting down the system, similar to sleeping.
    837      */
    838     boolean mShuttingDown = false;
    839 
    840     /**
    841      * Current sequence id for oom_adj computation traversal.
    842      */
    843     int mAdjSeq = 0;
    844 
    845     /**
    846      * Current sequence id for process LRU updating.
    847      */
    848     int mLruSeq = 0;
    849 
    850     /**
    851      * Keep track of the non-cached/empty process we last found, to help
    852      * determine how to distribute cached/empty processes next time.
    853      */
    854     int mNumNonCachedProcs = 0;
    855 
    856     /**
    857      * Keep track of the number of cached hidden procs, to balance oom adj
    858      * distribution between those and empty procs.
    859      */
    860     int mNumCachedHiddenProcs = 0;
    861 
    862     /**
    863      * Keep track of the number of service processes we last found, to
    864      * determine on the next iteration which should be B services.
    865      */
    866     int mNumServiceProcs = 0;
    867     int mNewNumAServiceProcs = 0;
    868     int mNewNumServiceProcs = 0;
    869 
    870     /**
    871      * Allow the current computed overall memory level of the system to go down?
    872      * This is set to false when we are killing processes for reasons other than
    873      * memory management, so that the now smaller process list will not be taken as
    874      * an indication that memory is tighter.
    875      */
    876     boolean mAllowLowerMemLevel = false;
    877 
    878     /**
    879      * The last computed memory level, for holding when we are in a state that
    880      * processes are going away for other reasons.
    881      */
    882     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
    883 
    884     /**
    885      * The last total number of process we have, to determine if changes actually look
    886      * like a shrinking number of process due to lower RAM.
    887      */
    888     int mLastNumProcesses;
    889 
    890     /**
    891      * The uptime of the last time we performed idle maintenance.
    892      */
    893     long mLastIdleTime = SystemClock.uptimeMillis();
    894 
    895     /**
    896      * Total time spent with RAM that has been added in the past since the last idle time.
    897      */
    898     long mLowRamTimeSinceLastIdle = 0;
    899 
    900     /**
    901      * If RAM is currently low, when that horrible situatin started.
    902      */
    903     long mLowRamStartTime = 0;
    904 
    905     /**
    906      * This is set if we had to do a delayed dexopt of an app before launching
    907      * it, to increasing the ANR timeouts in that case.
    908      */
    909     boolean mDidDexOpt;
    910 
    911     String mDebugApp = null;
    912     boolean mWaitForDebugger = false;
    913     boolean mDebugTransient = false;
    914     String mOrigDebugApp = null;
    915     boolean mOrigWaitForDebugger = false;
    916     boolean mAlwaysFinishActivities = false;
    917     IActivityController mController = null;
    918     String mProfileApp = null;
    919     ProcessRecord mProfileProc = null;
    920     String mProfileFile;
    921     ParcelFileDescriptor mProfileFd;
    922     int mProfileType = 0;
    923     boolean mAutoStopProfiler = false;
    924     String mOpenGlTraceApp = null;
    925 
    926     static class ProcessChangeItem {
    927         static final int CHANGE_ACTIVITIES = 1<<0;
    928         static final int CHANGE_IMPORTANCE= 1<<1;
    929         int changes;
    930         int uid;
    931         int pid;
    932         int importance;
    933         boolean foregroundActivities;
    934     }
    935 
    936     final RemoteCallbackList<IProcessObserver> mProcessObservers
    937             = new RemoteCallbackList<IProcessObserver>();
    938     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    939 
    940     final ArrayList<ProcessChangeItem> mPendingProcessChanges
    941             = new ArrayList<ProcessChangeItem>();
    942     final ArrayList<ProcessChangeItem> mAvailProcessChanges
    943             = new ArrayList<ProcessChangeItem>();
    944 
    945     /**
    946      * Runtime CPU use collection thread.  This object's lock is used to
    947      * protect all related state.
    948      */
    949     final Thread mProcessCpuThread;
    950 
    951     /**
    952      * Used to collect process stats when showing not responding dialog.
    953      * Protected by mProcessCpuThread.
    954      */
    955     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
    956             MONITOR_THREAD_CPU_USAGE);
    957     final AtomicLong mLastCpuTime = new AtomicLong(0);
    958     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
    959 
    960     long mLastWriteTime = 0;
    961 
    962     /**
    963      * Used to retain an update lock when the foreground activity is in
    964      * immersive mode.
    965      */
    966     final UpdateLock mUpdateLock = new UpdateLock("immersive");
    967 
    968     /**
    969      * Set to true after the system has finished booting.
    970      */
    971     boolean mBooted = false;
    972 
    973     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
    974     int mProcessLimitOverride = -1;
    975 
    976     WindowManagerService mWindowManager;
    977 
    978     static ActivityManagerService mSelf;
    979     static ActivityThread mSystemThread;
    980 
    981     int mCurrentUserId = 0;
    982     private UserManagerService mUserManager;
    983 
    984     private final class AppDeathRecipient implements IBinder.DeathRecipient {
    985         final ProcessRecord mApp;
    986         final int mPid;
    987         final IApplicationThread mAppThread;
    988 
    989         AppDeathRecipient(ProcessRecord app, int pid,
    990                 IApplicationThread thread) {
    991             if (localLOGV) Slog.v(
    992                 TAG, "New death recipient " + this
    993                 + " for thread " + thread.asBinder());
    994             mApp = app;
    995             mPid = pid;
    996             mAppThread = thread;
    997         }
    998 
    999         @Override
   1000         public void binderDied() {
   1001             if (localLOGV) Slog.v(
   1002                 TAG, "Death received in " + this
   1003                 + " for thread " + mAppThread.asBinder());
   1004             synchronized(ActivityManagerService.this) {
   1005                 appDiedLocked(mApp, mPid, mAppThread);
   1006             }
   1007         }
   1008     }
   1009 
   1010     static final int SHOW_ERROR_MSG = 1;
   1011     static final int SHOW_NOT_RESPONDING_MSG = 2;
   1012     static final int SHOW_FACTORY_ERROR_MSG = 3;
   1013     static final int UPDATE_CONFIGURATION_MSG = 4;
   1014     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1015     static final int WAIT_FOR_DEBUGGER_MSG = 6;
   1016     static final int SERVICE_TIMEOUT_MSG = 12;
   1017     static final int UPDATE_TIME_ZONE = 13;
   1018     static final int SHOW_UID_ERROR_MSG = 14;
   1019     static final int IM_FEELING_LUCKY_MSG = 15;
   1020     static final int PROC_START_TIMEOUT_MSG = 20;
   1021     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1022     static final int KILL_APPLICATION_MSG = 22;
   1023     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1024     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1025     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1026     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
   1027     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1028     static final int CLEAR_DNS_CACHE_MSG = 28;
   1029     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1030     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
   1031     static final int DISPATCH_PROCESSES_CHANGED = 31;
   1032     static final int DISPATCH_PROCESS_DIED = 32;
   1033     static final int REPORT_MEM_USAGE_MSG = 33;
   1034     static final int REPORT_USER_SWITCH_MSG = 34;
   1035     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1036     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1037     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1038     static final int PERSIST_URI_GRANTS_MSG = 38;
   1039     static final int REQUEST_ALL_PSS_MSG = 39;
   1040 
   1041     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1042     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1043     static final int FIRST_COMPAT_MODE_MSG = 300;
   1044     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1045 
   1046     AlertDialog mUidAlert;
   1047     CompatModeDialog mCompatModeDialog;
   1048     long mLastMemUsageReportTime = 0;
   1049 
   1050     /**
   1051      * Flag whether the current user is a "monkey", i.e. whether
   1052      * the UI is driven by a UI automation tool.
   1053      */
   1054     private boolean mUserIsMonkey;
   1055 
   1056     final Handler mHandler = new Handler() {
   1057         //public Handler() {
   1058         //    if (localLOGV) Slog.v(TAG, "Handler started!");
   1059         //}
   1060 
   1061         @Override
   1062         public void handleMessage(Message msg) {
   1063             switch (msg.what) {
   1064             case SHOW_ERROR_MSG: {
   1065                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1066                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   1067                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   1068                 synchronized (ActivityManagerService.this) {
   1069                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1070                     AppErrorResult res = (AppErrorResult) data.get("result");
   1071                     if (proc != null && proc.crashDialog != null) {
   1072                         Slog.e(TAG, "App already has crash dialog: " + proc);
   1073                         if (res != null) {
   1074                             res.set(0);
   1075                         }
   1076                         return;
   1077                     }
   1078                     if (!showBackground && UserHandle.getAppId(proc.uid)
   1079                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
   1080                             && proc.pid != MY_PID) {
   1081                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
   1082                         if (res != null) {
   1083                             res.set(0);
   1084                         }
   1085                         return;
   1086                     }
   1087                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1088                         Dialog d = new AppErrorDialog(mContext,
   1089                                 ActivityManagerService.this, res, proc);
   1090                         d.show();
   1091                         proc.crashDialog = d;
   1092                     } else {
   1093                         // The device is asleep, so just pretend that the user
   1094                         // saw a crash dialog and hit "force quit".
   1095                         if (res != null) {
   1096                             res.set(0);
   1097                         }
   1098                     }
   1099                 }
   1100 
   1101                 ensureBootCompleted();
   1102             } break;
   1103             case SHOW_NOT_RESPONDING_MSG: {
   1104                 synchronized (ActivityManagerService.this) {
   1105                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1106                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1107                     if (proc != null && proc.anrDialog != null) {
   1108                         Slog.e(TAG, "App already has anr dialog: " + proc);
   1109                         return;
   1110                     }
   1111 
   1112                     Intent intent = new Intent("android.intent.action.ANR");
   1113                     if (!mProcessesReady) {
   1114                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   1115                                 | Intent.FLAG_RECEIVER_FOREGROUND);
   1116                     }
   1117                     broadcastIntentLocked(null, null, intent,
   1118                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   1119                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   1120 
   1121                     if (mShowDialogs) {
   1122                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1123                                 mContext, proc, (ActivityRecord)data.get("activity"),
   1124                                 msg.arg1 != 0);
   1125                         d.show();
   1126                         proc.anrDialog = d;
   1127                     } else {
   1128                         // Just kill the app if there is no dialog to be shown.
   1129                         killAppAtUsersRequest(proc, null);
   1130                     }
   1131                 }
   1132 
   1133                 ensureBootCompleted();
   1134             } break;
   1135             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1136                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1137                 synchronized (ActivityManagerService.this) {
   1138                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1139                     if (proc == null) {
   1140                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1141                         break;
   1142                     }
   1143                     if (proc.crashDialog != null) {
   1144                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1145                         return;
   1146                     }
   1147                     AppErrorResult res = (AppErrorResult) data.get("result");
   1148                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1149                         Dialog d = new StrictModeViolationDialog(mContext,
   1150                                 ActivityManagerService.this, res, proc);
   1151                         d.show();
   1152                         proc.crashDialog = d;
   1153                     } else {
   1154                         // The device is asleep, so just pretend that the user
   1155                         // saw a crash dialog and hit "force quit".
   1156                         res.set(0);
   1157                     }
   1158                 }
   1159                 ensureBootCompleted();
   1160             } break;
   1161             case SHOW_FACTORY_ERROR_MSG: {
   1162                 Dialog d = new FactoryErrorDialog(
   1163                     mContext, msg.getData().getCharSequence("msg"));
   1164                 d.show();
   1165                 ensureBootCompleted();
   1166             } break;
   1167             case UPDATE_CONFIGURATION_MSG: {
   1168                 final ContentResolver resolver = mContext.getContentResolver();
   1169                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1170             } break;
   1171             case GC_BACKGROUND_PROCESSES_MSG: {
   1172                 synchronized (ActivityManagerService.this) {
   1173                     performAppGcsIfAppropriateLocked();
   1174                 }
   1175             } break;
   1176             case WAIT_FOR_DEBUGGER_MSG: {
   1177                 synchronized (ActivityManagerService.this) {
   1178                     ProcessRecord app = (ProcessRecord)msg.obj;
   1179                     if (msg.arg1 != 0) {
   1180                         if (!app.waitedForDebugger) {
   1181                             Dialog d = new AppWaitingForDebuggerDialog(
   1182                                     ActivityManagerService.this,
   1183                                     mContext, app);
   1184                             app.waitDialog = d;
   1185                             app.waitedForDebugger = true;
   1186                             d.show();
   1187                         }
   1188                     } else {
   1189                         if (app.waitDialog != null) {
   1190                             app.waitDialog.dismiss();
   1191                             app.waitDialog = null;
   1192                         }
   1193                     }
   1194                 }
   1195             } break;
   1196             case SERVICE_TIMEOUT_MSG: {
   1197                 if (mDidDexOpt) {
   1198                     mDidDexOpt = false;
   1199                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1200                     nmsg.obj = msg.obj;
   1201                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1202                     return;
   1203                 }
   1204                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1205             } break;
   1206             case UPDATE_TIME_ZONE: {
   1207                 synchronized (ActivityManagerService.this) {
   1208                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1209                         ProcessRecord r = mLruProcesses.get(i);
   1210                         if (r.thread != null) {
   1211                             try {
   1212                                 r.thread.updateTimeZone();
   1213                             } catch (RemoteException ex) {
   1214                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1215                             }
   1216                         }
   1217                     }
   1218                 }
   1219             } break;
   1220             case CLEAR_DNS_CACHE_MSG: {
   1221                 synchronized (ActivityManagerService.this) {
   1222                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1223                         ProcessRecord r = mLruProcesses.get(i);
   1224                         if (r.thread != null) {
   1225                             try {
   1226                                 r.thread.clearDnsCache();
   1227                             } catch (RemoteException ex) {
   1228                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1229                             }
   1230                         }
   1231                     }
   1232                 }
   1233             } break;
   1234             case UPDATE_HTTP_PROXY_MSG: {
   1235                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1236                 String host = "";
   1237                 String port = "";
   1238                 String exclList = "";
   1239                 String pacFileUrl = null;
   1240                 if (proxy != null) {
   1241                     host = proxy.getHost();
   1242                     port = Integer.toString(proxy.getPort());
   1243                     exclList = proxy.getExclusionList();
   1244                     pacFileUrl = proxy.getPacFileUrl();
   1245                 }
   1246                 synchronized (ActivityManagerService.this) {
   1247                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1248                         ProcessRecord r = mLruProcesses.get(i);
   1249                         if (r.thread != null) {
   1250                             try {
   1251                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1252                             } catch (RemoteException ex) {
   1253                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1254                                         r.info.processName);
   1255                             }
   1256                         }
   1257                     }
   1258                 }
   1259             } break;
   1260             case SHOW_UID_ERROR_MSG: {
   1261                 String title = "System UIDs Inconsistent";
   1262                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1263                         + " data partition or your device will be unstable.";
   1264                 Log.e(TAG, title + ": " + text);
   1265                 if (mShowDialogs) {
   1266                     // XXX This is a temporary dialog, no need to localize.
   1267                     AlertDialog d = new BaseErrorDialog(mContext);
   1268                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1269                     d.setCancelable(false);
   1270                     d.setTitle(title);
   1271                     d.setMessage(text);
   1272                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1273                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1274                     mUidAlert = d;
   1275                     d.show();
   1276                 }
   1277             } break;
   1278             case IM_FEELING_LUCKY_MSG: {
   1279                 if (mUidAlert != null) {
   1280                     mUidAlert.dismiss();
   1281                     mUidAlert = null;
   1282                 }
   1283             } break;
   1284             case PROC_START_TIMEOUT_MSG: {
   1285                 if (mDidDexOpt) {
   1286                     mDidDexOpt = false;
   1287                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1288                     nmsg.obj = msg.obj;
   1289                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1290                     return;
   1291                 }
   1292                 ProcessRecord app = (ProcessRecord)msg.obj;
   1293                 synchronized (ActivityManagerService.this) {
   1294                     processStartTimedOutLocked(app);
   1295                 }
   1296             } break;
   1297             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1298                 synchronized (ActivityManagerService.this) {
   1299                     doPendingActivityLaunchesLocked(true);
   1300                 }
   1301             } break;
   1302             case KILL_APPLICATION_MSG: {
   1303                 synchronized (ActivityManagerService.this) {
   1304                     int appid = msg.arg1;
   1305                     boolean restart = (msg.arg2 == 1);
   1306                     Bundle bundle = (Bundle)msg.obj;
   1307                     String pkg = bundle.getString("pkg");
   1308                     String reason = bundle.getString("reason");
   1309                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1310                             UserHandle.USER_ALL, reason);
   1311                 }
   1312             } break;
   1313             case FINALIZE_PENDING_INTENT_MSG: {
   1314                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1315             } break;
   1316             case POST_HEAVY_NOTIFICATION_MSG: {
   1317                 INotificationManager inm = NotificationManager.getService();
   1318                 if (inm == null) {
   1319                     return;
   1320                 }
   1321 
   1322                 ActivityRecord root = (ActivityRecord)msg.obj;
   1323                 ProcessRecord process = root.app;
   1324                 if (process == null) {
   1325                     return;
   1326                 }
   1327 
   1328                 try {
   1329                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1330                     String text = mContext.getString(R.string.heavy_weight_notification,
   1331                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1332                     Notification notification = new Notification();
   1333                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1334                     notification.when = 0;
   1335                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1336                     notification.tickerText = text;
   1337                     notification.defaults = 0; // please be quiet
   1338                     notification.sound = null;
   1339                     notification.vibrate = null;
   1340                     notification.setLatestEventInfo(context, text,
   1341                             mContext.getText(R.string.heavy_weight_notification_detail),
   1342                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1343                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1344                                     new UserHandle(root.userId)));
   1345 
   1346                     try {
   1347                         int[] outId = new int[1];
   1348                         inm.enqueueNotificationWithTag("android", "android", null,
   1349                                 R.string.heavy_weight_notification,
   1350                                 notification, outId, root.userId);
   1351                     } catch (RuntimeException e) {
   1352                         Slog.w(ActivityManagerService.TAG,
   1353                                 "Error showing notification for heavy-weight app", e);
   1354                     } catch (RemoteException e) {
   1355                     }
   1356                 } catch (NameNotFoundException e) {
   1357                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1358                 }
   1359             } break;
   1360             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1361                 INotificationManager inm = NotificationManager.getService();
   1362                 if (inm == null) {
   1363                     return;
   1364                 }
   1365                 try {
   1366                     inm.cancelNotificationWithTag("android", null,
   1367                             R.string.heavy_weight_notification,  msg.arg1);
   1368                 } catch (RuntimeException e) {
   1369                     Slog.w(ActivityManagerService.TAG,
   1370                             "Error canceling notification for service", e);
   1371                 } catch (RemoteException e) {
   1372                 }
   1373             } break;
   1374             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1375                 synchronized (ActivityManagerService.this) {
   1376                     checkExcessivePowerUsageLocked(true);
   1377                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1378                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1379                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1380                 }
   1381             } break;
   1382             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1383                 synchronized (ActivityManagerService.this) {
   1384                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1385                     if (mCompatModeDialog != null) {
   1386                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1387                                 ar.info.applicationInfo.packageName)) {
   1388                             return;
   1389                         }
   1390                         mCompatModeDialog.dismiss();
   1391                         mCompatModeDialog = null;
   1392                     }
   1393                     if (ar != null && false) {
   1394                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1395                                 ar.packageName)) {
   1396                             int mode = mCompatModePackages.computeCompatModeLocked(
   1397                                     ar.info.applicationInfo);
   1398                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1399                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1400                                 mCompatModeDialog = new CompatModeDialog(
   1401                                         ActivityManagerService.this, mContext,
   1402                                         ar.info.applicationInfo);
   1403                                 mCompatModeDialog.show();
   1404                             }
   1405                         }
   1406                     }
   1407                 }
   1408                 break;
   1409             }
   1410             case DISPATCH_PROCESSES_CHANGED: {
   1411                 dispatchProcessesChanged();
   1412                 break;
   1413             }
   1414             case DISPATCH_PROCESS_DIED: {
   1415                 final int pid = msg.arg1;
   1416                 final int uid = msg.arg2;
   1417                 dispatchProcessDied(pid, uid);
   1418                 break;
   1419             }
   1420             case REPORT_MEM_USAGE_MSG: {
   1421                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1422                 Thread thread = new Thread() {
   1423                     @Override public void run() {
   1424                         final SparseArray<ProcessMemInfo> infoMap
   1425                                 = new SparseArray<ProcessMemInfo>(memInfos.size());
   1426                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1427                             ProcessMemInfo mi = memInfos.get(i);
   1428                             infoMap.put(mi.pid, mi);
   1429                         }
   1430                         updateCpuStatsNow();
   1431                         synchronized (mProcessCpuThread) {
   1432                             final int N = mProcessCpuTracker.countStats();
   1433                             for (int i=0; i<N; i++) {
   1434                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   1435                                 if (st.vsize > 0) {
   1436                                     long pss = Debug.getPss(st.pid, null);
   1437                                     if (pss > 0) {
   1438                                         if (infoMap.indexOfKey(st.pid) < 0) {
   1439                                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   1440                                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   1441                                             mi.pss = pss;
   1442                                             memInfos.add(mi);
   1443                                         }
   1444                                     }
   1445                                 }
   1446                             }
   1447                         }
   1448 
   1449                         long totalPss = 0;
   1450                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1451                             ProcessMemInfo mi = memInfos.get(i);
   1452                             if (mi.pss == 0) {
   1453                                 mi.pss = Debug.getPss(mi.pid, null);
   1454                             }
   1455                             totalPss += mi.pss;
   1456                         }
   1457                         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   1458                             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   1459                                 if (lhs.oomAdj != rhs.oomAdj) {
   1460                                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   1461                                 }
   1462                                 if (lhs.pss != rhs.pss) {
   1463                                     return lhs.pss < rhs.pss ? 1 : -1;
   1464                                 }
   1465                                 return 0;
   1466                             }
   1467                         });
   1468 
   1469                         StringBuilder tag = new StringBuilder(128);
   1470                         StringBuilder stack = new StringBuilder(128);
   1471                         tag.append("Low on memory -- ");
   1472                         appendMemBucket(tag, totalPss, "total", false);
   1473                         appendMemBucket(stack, totalPss, "total", true);
   1474 
   1475                         StringBuilder logBuilder = new StringBuilder(1024);
   1476                         logBuilder.append("Low on memory:\n");
   1477 
   1478                         boolean firstLine = true;
   1479                         int lastOomAdj = Integer.MIN_VALUE;
   1480                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1481                             ProcessMemInfo mi = memInfos.get(i);
   1482 
   1483                             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   1484                                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   1485                                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   1486                                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   1487                                 if (lastOomAdj != mi.oomAdj) {
   1488                                     lastOomAdj = mi.oomAdj;
   1489                                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1490                                         tag.append(" / ");
   1491                                     }
   1492                                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   1493                                         if (firstLine) {
   1494                                             stack.append(":");
   1495                                             firstLine = false;
   1496                                         }
   1497                                         stack.append("\n\t at ");
   1498                                     } else {
   1499                                         stack.append("$");
   1500                                     }
   1501                                 } else {
   1502                                     tag.append(" ");
   1503                                     stack.append("$");
   1504                                 }
   1505                                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1506                                     appendMemBucket(tag, mi.pss, mi.name, false);
   1507                                 }
   1508                                 appendMemBucket(stack, mi.pss, mi.name, true);
   1509                                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   1510                                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   1511                                     stack.append("(");
   1512                                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   1513                                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   1514                                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   1515                                             stack.append(":");
   1516                                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   1517                                         }
   1518                                     }
   1519                                     stack.append(")");
   1520                                 }
   1521                             }
   1522 
   1523                             logBuilder.append("  ");
   1524                             logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
   1525                             logBuilder.append(' ');
   1526                             logBuilder.append(ProcessList.makeProcStateString(mi.procState));
   1527                             logBuilder.append(' ');
   1528                             ProcessList.appendRamKb(logBuilder, mi.pss);
   1529                             logBuilder.append(" kB: ");
   1530                             logBuilder.append(mi.name);
   1531                             logBuilder.append(" (");
   1532                             logBuilder.append(mi.pid);
   1533                             logBuilder.append(") ");
   1534                             logBuilder.append(mi.adjType);
   1535                             logBuilder.append('\n');
   1536                             if (mi.adjReason != null) {
   1537                                 logBuilder.append("                      ");
   1538                                 logBuilder.append(mi.adjReason);
   1539                                 logBuilder.append('\n');
   1540                             }
   1541                         }
   1542 
   1543                         logBuilder.append("           ");
   1544                         ProcessList.appendRamKb(logBuilder, totalPss);
   1545                         logBuilder.append(" kB: TOTAL\n");
   1546 
   1547                         long[] infos = new long[Debug.MEMINFO_COUNT];
   1548                         Debug.getMemInfo(infos);
   1549                         logBuilder.append("  MemInfo: ");
   1550                         logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
   1551                         logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
   1552                         logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
   1553                         logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
   1554                         logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
   1555                         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   1556                             logBuilder.append("  ZRAM: ");
   1557                             logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
   1558                             logBuilder.append(" kB RAM, ");
   1559                             logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
   1560                             logBuilder.append(" kB swap total, ");
   1561                             logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
   1562                             logBuilder.append(" kB swap free\n");
   1563                         }
   1564                         Slog.i(TAG, logBuilder.toString());
   1565 
   1566                         StringBuilder dropBuilder = new StringBuilder(1024);
   1567                         /*
   1568                         StringWriter oomSw = new StringWriter();
   1569                         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   1570                         StringWriter catSw = new StringWriter();
   1571                         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1572                         String[] emptyArgs = new String[] { };
   1573                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   1574                         oomPw.flush();
   1575                         String oomString = oomSw.toString();
   1576                         */
   1577                         dropBuilder.append(stack);
   1578                         dropBuilder.append('\n');
   1579                         dropBuilder.append('\n');
   1580                         dropBuilder.append(logBuilder);
   1581                         dropBuilder.append('\n');
   1582                         /*
   1583                         dropBuilder.append(oomString);
   1584                         dropBuilder.append('\n');
   1585                         */
   1586                         StringWriter catSw = new StringWriter();
   1587                         synchronized (ActivityManagerService.this) {
   1588                             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1589                             String[] emptyArgs = new String[] { };
   1590                             catPw.println();
   1591                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1592                             catPw.println();
   1593                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   1594                                     false, false, null);
   1595                             catPw.println();
   1596                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1597                             catPw.flush();
   1598                         }
   1599                         dropBuilder.append(catSw.toString());
   1600                         addErrorToDropBox("lowmem", null, "system_server", null,
   1601                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1602                         //Slog.i(TAG, "Sent to dropbox:");
   1603                         //Slog.i(TAG, dropBuilder.toString());
   1604                         synchronized (ActivityManagerService.this) {
   1605                             long now = SystemClock.uptimeMillis();
   1606                             if (mLastMemUsageReportTime < now) {
   1607                                 mLastMemUsageReportTime = now;
   1608                             }
   1609                         }
   1610                     }
   1611                 };
   1612                 thread.start();
   1613                 break;
   1614             }
   1615             case REPORT_USER_SWITCH_MSG: {
   1616                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1617                 break;
   1618             }
   1619             case CONTINUE_USER_SWITCH_MSG: {
   1620                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1621                 break;
   1622             }
   1623             case USER_SWITCH_TIMEOUT_MSG: {
   1624                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1625                 break;
   1626             }
   1627             case IMMERSIVE_MODE_LOCK_MSG: {
   1628                 final boolean nextState = (msg.arg1 != 0);
   1629                 if (mUpdateLock.isHeld() != nextState) {
   1630                     if (DEBUG_IMMERSIVE) {
   1631                         final ActivityRecord r = (ActivityRecord) msg.obj;
   1632                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
   1633                     }
   1634                     if (nextState) {
   1635                         mUpdateLock.acquire();
   1636                     } else {
   1637                         mUpdateLock.release();
   1638                     }
   1639                 }
   1640                 break;
   1641             }
   1642             case PERSIST_URI_GRANTS_MSG: {
   1643                 writeGrantedUriPermissions();
   1644                 break;
   1645             }
   1646             case REQUEST_ALL_PSS_MSG: {
   1647                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1648                 break;
   1649             }
   1650             }
   1651         }
   1652     };
   1653 
   1654     static final int COLLECT_PSS_BG_MSG = 1;
   1655 
   1656     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   1657         @Override
   1658         public void handleMessage(Message msg) {
   1659             switch (msg.what) {
   1660             case COLLECT_PSS_BG_MSG: {
   1661                 int i=0, num=0;
   1662                 long start = SystemClock.uptimeMillis();
   1663                 long[] tmp = new long[1];
   1664                 do {
   1665                     ProcessRecord proc;
   1666                     int procState;
   1667                     int pid;
   1668                     synchronized (ActivityManagerService.this) {
   1669                         if (i >= mPendingPssProcesses.size()) {
   1670                             if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
   1671                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
   1672                             mPendingPssProcesses.clear();
   1673                             return;
   1674                         }
   1675                         proc = mPendingPssProcesses.get(i);
   1676                         procState = proc.pssProcState;
   1677                         if (proc.thread != null && procState == proc.setProcState) {
   1678                             pid = proc.pid;
   1679                         } else {
   1680                             proc = null;
   1681                             pid = 0;
   1682                         }
   1683                         i++;
   1684                     }
   1685                     if (proc != null) {
   1686                         long pss = Debug.getPss(pid, tmp);
   1687                         synchronized (ActivityManagerService.this) {
   1688                             if (proc.thread != null && proc.setProcState == procState
   1689                                     && proc.pid == pid) {
   1690                                 num++;
   1691                                 proc.lastPssTime = SystemClock.uptimeMillis();
   1692                                 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
   1693                                 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
   1694                                         + ": " + pss + " lastPss=" + proc.lastPss
   1695                                         + " state=" + ProcessList.makeProcStateString(procState));
   1696                                 if (proc.initialIdlePss == 0) {
   1697                                     proc.initialIdlePss = pss;
   1698                                 }
   1699                                 proc.lastPss = pss;
   1700                                 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   1701                                     proc.lastCachedPss = pss;
   1702                                 }
   1703                             }
   1704                         }
   1705                     }
   1706                 } while (true);
   1707             }
   1708             }
   1709         }
   1710     };
   1711 
   1712     public static void setSystemProcess() {
   1713         try {
   1714             ActivityManagerService m = mSelf;
   1715 
   1716             ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
   1717             ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
   1718             ServiceManager.addService("meminfo", new MemBinder(m));
   1719             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1720             ServiceManager.addService("dbinfo", new DbBinder(m));
   1721             if (MONITOR_CPU_USAGE) {
   1722                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1723             }
   1724             ServiceManager.addService("permission", new PermissionController(m));
   1725 
   1726             ApplicationInfo info =
   1727                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1728                             "android", STOCK_PM_FLAGS);
   1729             mSystemThread.installSystemApplicationInfo(info);
   1730 
   1731             synchronized (mSelf) {
   1732                 ProcessRecord app = mSelf.newProcessRecordLocked(info,
   1733                         info.processName, false);
   1734                 app.persistent = true;
   1735                 app.pid = MY_PID;
   1736                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1737                 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
   1738                 mSelf.mProcessNames.put(app.processName, app.uid, app);
   1739                 synchronized (mSelf.mPidsSelfLocked) {
   1740                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1741                 }
   1742                 mSelf.updateLruProcessLocked(app, true, false);
   1743             }
   1744         } catch (PackageManager.NameNotFoundException e) {
   1745             throw new RuntimeException(
   1746                     "Unable to find android system package", e);
   1747         }
   1748     }
   1749 
   1750     public void setWindowManager(WindowManagerService wm) {
   1751         mWindowManager = wm;
   1752         mStackSupervisor.setWindowManager(wm);
   1753         wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
   1754     }
   1755 
   1756     public void startObservingNativeCrashes() {
   1757         final NativeCrashListener ncl = new NativeCrashListener();
   1758         ncl.start();
   1759     }
   1760 
   1761     public static final Context main(int factoryTest) {
   1762         AThread thr = new AThread();
   1763         thr.start();
   1764 
   1765         synchronized (thr) {
   1766             while (thr.mService == null) {
   1767                 try {
   1768                     thr.wait();
   1769                 } catch (InterruptedException e) {
   1770                 }
   1771             }
   1772         }
   1773 
   1774         ActivityManagerService m = thr.mService;
   1775         mSelf = m;
   1776         ActivityThread at = ActivityThread.systemMain();
   1777         mSystemThread = at;
   1778         Context context = at.getSystemContext();
   1779         context.setTheme(android.R.style.Theme_Holo);
   1780         m.mContext = context;
   1781         m.mFactoryTest = factoryTest;
   1782         m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
   1783 
   1784         m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
   1785 
   1786         m.mBatteryStatsService.publish(context);
   1787         m.mUsageStatsService.publish(context);
   1788         m.mAppOpsService.publish(context);
   1789 
   1790         synchronized (thr) {
   1791             thr.mReady = true;
   1792             thr.notifyAll();
   1793         }
   1794 
   1795         m.startRunning(null, null, null, null);
   1796 
   1797         return context;
   1798     }
   1799 
   1800     public static ActivityManagerService self() {
   1801         return mSelf;
   1802     }
   1803 
   1804     public IAppOpsService getAppOpsService() {
   1805         return mAppOpsService;
   1806     }
   1807 
   1808     static class AThread extends Thread {
   1809         ActivityManagerService mService;
   1810         Looper mLooper;
   1811         boolean mReady = false;
   1812 
   1813         public AThread() {
   1814             super("ActivityManager");
   1815         }
   1816 
   1817         @Override
   1818         public void run() {
   1819             Looper.prepare();
   1820 
   1821             android.os.Process.setThreadPriority(
   1822                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1823             android.os.Process.setCanSelfBackground(false);
   1824 
   1825             ActivityManagerService m = new ActivityManagerService();
   1826 
   1827             synchronized (this) {
   1828                 mService = m;
   1829                 mLooper = Looper.myLooper();
   1830                 Watchdog.getInstance().addThread(new Handler(mLooper), getName());
   1831                 notifyAll();
   1832             }
   1833 
   1834             synchronized (this) {
   1835                 while (!mReady) {
   1836                     try {
   1837                         wait();
   1838                     } catch (InterruptedException e) {
   1839                     }
   1840                 }
   1841             }
   1842 
   1843             // For debug builds, log event loop stalls to dropbox for analysis.
   1844             if (StrictMode.conditionallyEnableDebugLogging()) {
   1845                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1846             }
   1847 
   1848             Looper.loop();
   1849         }
   1850     }
   1851 
   1852     static class MemBinder extends Binder {
   1853         ActivityManagerService mActivityManagerService;
   1854         MemBinder(ActivityManagerService activityManagerService) {
   1855             mActivityManagerService = activityManagerService;
   1856         }
   1857 
   1858         @Override
   1859         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1860             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1861                     != PackageManager.PERMISSION_GRANTED) {
   1862                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1863                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1864                         + " without permission " + android.Manifest.permission.DUMP);
   1865                 return;
   1866             }
   1867 
   1868             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   1869         }
   1870     }
   1871 
   1872     static class GraphicsBinder extends Binder {
   1873         ActivityManagerService mActivityManagerService;
   1874         GraphicsBinder(ActivityManagerService activityManagerService) {
   1875             mActivityManagerService = activityManagerService;
   1876         }
   1877 
   1878         @Override
   1879         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1880             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1881                     != PackageManager.PERMISSION_GRANTED) {
   1882                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1883                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1884                         + " without permission " + android.Manifest.permission.DUMP);
   1885                 return;
   1886             }
   1887 
   1888             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1889         }
   1890     }
   1891 
   1892     static class DbBinder extends Binder {
   1893         ActivityManagerService mActivityManagerService;
   1894         DbBinder(ActivityManagerService activityManagerService) {
   1895             mActivityManagerService = activityManagerService;
   1896         }
   1897 
   1898         @Override
   1899         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1900             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1901                     != PackageManager.PERMISSION_GRANTED) {
   1902                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   1903                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1904                         + " without permission " + android.Manifest.permission.DUMP);
   1905                 return;
   1906             }
   1907 
   1908             mActivityManagerService.dumpDbInfo(fd, pw, args);
   1909         }
   1910     }
   1911 
   1912     static class CpuBinder extends Binder {
   1913         ActivityManagerService mActivityManagerService;
   1914         CpuBinder(ActivityManagerService activityManagerService) {
   1915             mActivityManagerService = activityManagerService;
   1916         }
   1917 
   1918         @Override
   1919         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1920             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1921                     != PackageManager.PERMISSION_GRANTED) {
   1922                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1923                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1924                         + " without permission " + android.Manifest.permission.DUMP);
   1925                 return;
   1926             }
   1927 
   1928             synchronized (mActivityManagerService.mProcessCpuThread) {
   1929                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   1930                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   1931                         SystemClock.uptimeMillis()));
   1932             }
   1933         }
   1934     }
   1935 
   1936     private ActivityManagerService() {
   1937         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1938 
   1939         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
   1940         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
   1941         mBroadcastQueues[0] = mFgBroadcastQueue;
   1942         mBroadcastQueues[1] = mBgBroadcastQueue;
   1943 
   1944         mServices = new ActiveServices(this);
   1945         mProviderMap = new ProviderMap(this);
   1946 
   1947         File dataDir = Environment.getDataDirectory();
   1948         File systemDir = new File(dataDir, "system");
   1949         systemDir.mkdirs();
   1950         mBatteryStatsService = new BatteryStatsService(new File(
   1951                 systemDir, "batterystats.bin").toString());
   1952         mBatteryStatsService.getActiveStatistics().readLocked();
   1953         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1954         mOnBattery = DEBUG_POWER ? true
   1955                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1956         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1957 
   1958         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   1959 
   1960         mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
   1961         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
   1962 
   1963         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   1964 
   1965         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
   1966 
   1967         // User 0 is the first and only user that runs at boot.
   1968         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   1969         mUserLru.add(Integer.valueOf(0));
   1970         updateStartedUserArrayLocked();
   1971 
   1972         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1973             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1974 
   1975         mConfiguration.setToDefaults();
   1976         mConfiguration.setLocale(Locale.getDefault());
   1977 
   1978         mConfigurationSeq = mConfiguration.seq = 1;
   1979         mProcessCpuTracker.init();
   1980 
   1981         mCompatModePackages = new CompatModePackages(this, systemDir);
   1982 
   1983         // Add ourself to the Watchdog monitors.
   1984         Watchdog.getInstance().addMonitor(this);
   1985 
   1986         mProcessCpuThread = new Thread("CpuTracker") {
   1987             @Override
   1988             public void run() {
   1989                 while (true) {
   1990                     try {
   1991                         try {
   1992                             synchronized(this) {
   1993                                 final long now = SystemClock.uptimeMillis();
   1994                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   1995                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   1996                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   1997                                 //        + ", write delay=" + nextWriteDelay);
   1998                                 if (nextWriteDelay < nextCpuDelay) {
   1999                                     nextCpuDelay = nextWriteDelay;
   2000                                 }
   2001                                 if (nextCpuDelay > 0) {
   2002                                     mProcessCpuMutexFree.set(true);
   2003                                     this.wait(nextCpuDelay);
   2004                                 }
   2005                             }
   2006                         } catch (InterruptedException e) {
   2007                         }
   2008                         updateCpuStatsNow();
   2009                     } catch (Exception e) {
   2010                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2011                     }
   2012                 }
   2013             }
   2014         };
   2015         mProcessCpuThread.start();
   2016     }
   2017 
   2018     @Override
   2019     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2020             throws RemoteException {
   2021         if (code == SYSPROPS_TRANSACTION) {
   2022             // We need to tell all apps about the system property change.
   2023             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2024             synchronized(this) {
   2025                 final int NP = mProcessNames.getMap().size();
   2026                 for (int ip=0; ip<NP; ip++) {
   2027                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2028                     final int NA = apps.size();
   2029                     for (int ia=0; ia<NA; ia++) {
   2030                         ProcessRecord app = apps.valueAt(ia);
   2031                         if (app.thread != null) {
   2032                             procs.add(app.thread.asBinder());
   2033                         }
   2034                     }
   2035                 }
   2036             }
   2037 
   2038             int N = procs.size();
   2039             for (int i=0; i<N; i++) {
   2040                 Parcel data2 = Parcel.obtain();
   2041                 try {
   2042                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2043                 } catch (RemoteException e) {
   2044                 }
   2045                 data2.recycle();
   2046             }
   2047         }
   2048         try {
   2049             return super.onTransact(code, data, reply, flags);
   2050         } catch (RuntimeException e) {
   2051             // The activity manager only throws security exceptions, so let's
   2052             // log all others.
   2053             if (!(e instanceof SecurityException)) {
   2054                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2055             }
   2056             throw e;
   2057         }
   2058     }
   2059 
   2060     void updateCpuStats() {
   2061         final long now = SystemClock.uptimeMillis();
   2062         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2063             return;
   2064         }
   2065         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2066             synchronized (mProcessCpuThread) {
   2067                 mProcessCpuThread.notify();
   2068             }
   2069         }
   2070     }
   2071 
   2072     void updateCpuStatsNow() {
   2073         synchronized (mProcessCpuThread) {
   2074             mProcessCpuMutexFree.set(false);
   2075             final long now = SystemClock.uptimeMillis();
   2076             boolean haveNewCpuStats = false;
   2077 
   2078             if (MONITOR_CPU_USAGE &&
   2079                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2080                 mLastCpuTime.set(now);
   2081                 haveNewCpuStats = true;
   2082                 mProcessCpuTracker.update();
   2083                 //Slog.i(TAG, mProcessCpu.printCurrentState());
   2084                 //Slog.i(TAG, "Total CPU usage: "
   2085                 //        + mProcessCpu.getTotalCpuPercent() + "%");
   2086 
   2087                 // Slog the cpu usage if the property is set.
   2088                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   2089                     int user = mProcessCpuTracker.getLastUserTime();
   2090                     int system = mProcessCpuTracker.getLastSystemTime();
   2091                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2092                     int irq = mProcessCpuTracker.getLastIrqTime();
   2093                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2094                     int idle = mProcessCpuTracker.getLastIdleTime();
   2095 
   2096                     int total = user + system + iowait + irq + softIrq + idle;
   2097                     if (total == 0) total = 1;
   2098 
   2099                     EventLog.writeEvent(EventLogTags.CPU,
   2100                             ((user+system+iowait+irq+softIrq) * 100) / total,
   2101                             (user * 100) / total,
   2102                             (system * 100) / total,
   2103                             (iowait * 100) / total,
   2104                             (irq * 100) / total,
   2105                             (softIrq * 100) / total);
   2106                 }
   2107             }
   2108 
   2109             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
   2110             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2111             synchronized(bstats) {
   2112                 synchronized(mPidsSelfLocked) {
   2113                     if (haveNewCpuStats) {
   2114                         if (mOnBattery) {
   2115                             int perc = bstats.startAddingCpuLocked();
   2116                             int totalUTime = 0;
   2117                             int totalSTime = 0;
   2118                             final int N = mProcessCpuTracker.countStats();
   2119                             for (int i=0; i<N; i++) {
   2120                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2121                                 if (!st.working) {
   2122                                     continue;
   2123                                 }
   2124                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2125                                 int otherUTime = (st.rel_utime*perc)/100;
   2126                                 int otherSTime = (st.rel_stime*perc)/100;
   2127                                 totalUTime += otherUTime;
   2128                                 totalSTime += otherSTime;
   2129                                 if (pr != null) {
   2130                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
   2131                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2132                                             st.rel_stime-otherSTime);
   2133                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2134                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   2135                                 } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
   2136                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2137                                     if (ps == null) {
   2138                                         st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
   2139                                                 "(Unknown)");
   2140                                     }
   2141                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2142                                             st.rel_stime-otherSTime);
   2143                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2144                                 } else {
   2145                                     BatteryStatsImpl.Uid.Proc ps =
   2146                                             bstats.getProcessStatsLocked(st.name, st.pid);
   2147                                     if (ps != null) {
   2148                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2149                                                 st.rel_stime-otherSTime);
   2150                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   2151                                     }
   2152                                 }
   2153                             }
   2154                             bstats.finishAddingCpuLocked(perc, totalUTime,
   2155                                     totalSTime, cpuSpeedTimes);
   2156                         }
   2157                     }
   2158                 }
   2159 
   2160                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2161                     mLastWriteTime = now;
   2162                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2163                 }
   2164             }
   2165         }
   2166     }
   2167 
   2168     @Override
   2169     public void batteryNeedsCpuUpdate() {
   2170         updateCpuStatsNow();
   2171     }
   2172 
   2173     @Override
   2174     public void batteryPowerChanged(boolean onBattery) {
   2175         // When plugging in, update the CPU stats first before changing
   2176         // the plug state.
   2177         updateCpuStatsNow();
   2178         synchronized (this) {
   2179             synchronized(mPidsSelfLocked) {
   2180                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2181             }
   2182         }
   2183     }
   2184 
   2185     /**
   2186      * Initialize the application bind args. These are passed to each
   2187      * process when the bindApplication() IPC is sent to the process. They're
   2188      * lazily setup to make sure the services are running when they're asked for.
   2189      */
   2190     private HashMap<String, IBinder> getCommonServicesLocked() {
   2191         if (mAppBindArgs == null) {
   2192             mAppBindArgs = new HashMap<String, IBinder>();
   2193 
   2194             // Setup the application init args
   2195             mAppBindArgs.put("package", ServiceManager.getService("package"));
   2196             mAppBindArgs.put("window", ServiceManager.getService("window"));
   2197             mAppBindArgs.put(Context.ALARM_SERVICE,
   2198                     ServiceManager.getService(Context.ALARM_SERVICE));
   2199         }
   2200         return mAppBindArgs;
   2201     }
   2202 
   2203     final void setFocusedActivityLocked(ActivityRecord r) {
   2204         if (mFocusedActivity != r) {
   2205             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
   2206             mFocusedActivity = r;
   2207             mStackSupervisor.setFocusedStack(r);
   2208             if (r != null) {
   2209                 mWindowManager.setFocusedApp(r.appToken, true);
   2210             }
   2211             applyUpdateLockStateLocked(r);
   2212         }
   2213     }
   2214 
   2215     @Override
   2216     public void setFocusedStack(int stackId) {
   2217         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
   2218         synchronized (ActivityManagerService.this) {
   2219             ActivityStack stack = mStackSupervisor.getStack(stackId);
   2220             if (stack != null) {
   2221                 ActivityRecord r = stack.topRunningActivityLocked(null);
   2222                 if (r != null) {
   2223                     setFocusedActivityLocked(r);
   2224                 }
   2225             }
   2226         }
   2227     }
   2228 
   2229     @Override
   2230     public void notifyActivityDrawn(IBinder token) {
   2231         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
   2232         synchronized (this) {
   2233             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
   2234             if (r != null) {
   2235                 r.task.stack.notifyActivityDrawnLocked(r);
   2236             }
   2237         }
   2238     }
   2239 
   2240     final void applyUpdateLockStateLocked(ActivityRecord r) {
   2241         // Modifications to the UpdateLock state are done on our handler, outside
   2242         // the activity manager's locks.  The new state is determined based on the
   2243         // state *now* of the relevant activity record.  The object is passed to
   2244         // the handler solely for logging detail, not to be consulted/modified.
   2245         final boolean nextState = r != null && r.immersive;
   2246         mHandler.sendMessage(
   2247                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   2248     }
   2249 
   2250     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   2251         Message msg = Message.obtain();
   2252         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
   2253         msg.obj = r.task.askedCompatMode ? null : r;
   2254         mHandler.sendMessage(msg);
   2255     }
   2256 
   2257     private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   2258             String what, Object obj, ProcessRecord srcApp) {
   2259         app.lastActivityTime = now;
   2260 
   2261         if (app.activities.size() > 0) {
   2262             // Don't want to touch dependent processes that are hosting activities.
   2263             return index;
   2264         }
   2265 
   2266         int lrui = mLruProcesses.lastIndexOf(app);
   2267         if (lrui < 0) {
   2268             Log.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   2269                     + what + " " + obj + " from " + srcApp);
   2270             return index;
   2271         }
   2272 
   2273         if (lrui >= index) {
   2274             // Don't want to cause this to move dependent processes *back* in the
   2275             // list as if they were less frequently used.
   2276             return index;
   2277         }
   2278 
   2279         if (lrui >= mLruProcessActivityStart) {
   2280             // Don't want to touch dependent processes that are hosting activities.
   2281             return index;
   2282         }
   2283 
   2284         mLruProcesses.remove(lrui);
   2285         if (index > 0) {
   2286             index--;
   2287         }
   2288         mLruProcesses.add(index, app);
   2289         return index;
   2290     }
   2291 
   2292     final void removeLruProcessLocked(ProcessRecord app) {
   2293         int lrui = mLruProcesses.lastIndexOf(app);
   2294         if (lrui >= 0) {
   2295             if (lrui <= mLruProcessActivityStart) {
   2296                 mLruProcessActivityStart--;
   2297             }
   2298             if (lrui <= mLruProcessServiceStart) {
   2299                 mLruProcessServiceStart--;
   2300             }
   2301             mLruProcesses.remove(lrui);
   2302         }
   2303     }
   2304 
   2305     final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean activityChange) {
   2306         final boolean hasActivity = app.activities.size() > 0;
   2307         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   2308         if (!activityChange && hasActivity) {
   2309             // The process has activties, so we are only going to allow activity-based
   2310             // adjustments move it.  It should be kept in the front of the list with other
   2311             // processes that have activities, and we don't want those to change their
   2312             // order except due to activity operations.
   2313             return;
   2314         }
   2315 
   2316         mLruSeq++;
   2317         final long now = SystemClock.uptimeMillis();
   2318         app.lastActivityTime = now;
   2319 
   2320         int lrui = mLruProcesses.lastIndexOf(app);
   2321 
   2322         if (lrui >= 0) {
   2323             if (lrui < mLruProcessActivityStart) {
   2324                 mLruProcessActivityStart--;
   2325             }
   2326             if (lrui < mLruProcessServiceStart) {
   2327                 mLruProcessServiceStart--;
   2328             }
   2329             mLruProcesses.remove(lrui);
   2330         }
   2331 
   2332         int nextIndex;
   2333         if (hasActivity) {
   2334             // Process has activities, put it at the very tipsy-top.
   2335             mLruProcesses.add(app);
   2336             nextIndex = mLruProcessActivityStart;
   2337         } else if (hasService) {
   2338             // Process has services, put it at the top of the service list.
   2339             mLruProcesses.add(mLruProcessActivityStart, app);
   2340             nextIndex = mLruProcessServiceStart;
   2341             mLruProcessActivityStart++;
   2342         } else  {
   2343             // Process not otherwise of interest, it goes to the top of the non-service area.
   2344             mLruProcesses.add(mLruProcessServiceStart, app);
   2345             nextIndex = mLruProcessServiceStart-1;
   2346             mLruProcessActivityStart++;
   2347             mLruProcessServiceStart++;
   2348         }
   2349 
   2350         // If the app is currently using a content provider or service,
   2351         // bump those processes as well.
   2352         for (int j=app.connections.size()-1; j>=0; j--) {
   2353             ConnectionRecord cr = app.connections.valueAt(j);
   2354             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   2355                     && cr.binding.service.app != null
   2356                     && cr.binding.service.app.lruSeq != mLruSeq) {
   2357                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   2358                         "service connection", cr, app);
   2359             }
   2360         }
   2361         for (int j=app.conProviders.size()-1; j>=0; j--) {
   2362             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   2363             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
   2364                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   2365                         "provider reference", cpr, app);
   2366             }
   2367         }
   2368 
   2369         //Slog.i(TAG, "Putting proc to front: " + app.processName);
   2370         if (oomAdj) {
   2371             updateOomAdjLocked();
   2372         }
   2373     }
   2374 
   2375     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   2376         if (uid == Process.SYSTEM_UID) {
   2377             // The system gets to run in any process.  If there are multiple
   2378             // processes with the same uid, just pick the first (this
   2379             // should never happen).
   2380             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   2381             if (procs == null) return null;
   2382             final int N = procs.size();
   2383             for (int i = 0; i < N; i++) {
   2384                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   2385             }
   2386         }
   2387         ProcessRecord proc = mProcessNames.get(processName, uid);
   2388         if (false && proc != null && !keepIfLarge
   2389                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   2390                 && proc.lastCachedPss >= 4000) {
   2391             // Turn this condition on to cause killing to happen regularly, for testing.
   2392             if (proc.baseProcessTracker != null) {
   2393                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2394             }
   2395             killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
   2396                     + "k from cached");
   2397         } else if (proc != null && !keepIfLarge
   2398                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   2399                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2400             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   2401             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   2402                 if (proc.baseProcessTracker != null) {
   2403                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2404                 }
   2405                 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
   2406                         + "k from cached");
   2407             }
   2408         }
   2409         return proc;
   2410     }
   2411 
   2412     void ensurePackageDexOpt(String packageName) {
   2413         IPackageManager pm = AppGlobals.getPackageManager();
   2414         try {
   2415             if (pm.performDexOpt(packageName)) {
   2416                 mDidDexOpt = true;
   2417             }
   2418         } catch (RemoteException e) {
   2419         }
   2420     }
   2421 
   2422     boolean isNextTransitionForward() {
   2423         int transit = mWindowManager.getPendingAppTransition();
   2424         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2425                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2426                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2427     }
   2428 
   2429     final ProcessRecord startProcessLocked(String processName,
   2430             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2431             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2432             boolean isolated, boolean keepIfLarge) {
   2433         ProcessRecord app;
   2434         if (!isolated) {
   2435             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   2436         } else {
   2437             // If this is an isolated process, it can't re-use an existing process.
   2438             app = null;
   2439         }
   2440         // We don't have to do anything more if:
   2441         // (1) There is an existing application record; and
   2442         // (2) The caller doesn't think it is dead, OR there is no thread
   2443         //     object attached to it so we know it couldn't have crashed; and
   2444         // (3) There is a pid assigned to it, so it is either starting or
   2445         //     already running.
   2446         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2447                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2448                 + " thread=" + (app != null ? app.thread : null)
   2449                 + " pid=" + (app != null ? app.pid : -1));
   2450         if (app != null && app.pid > 0) {
   2451             if (!knownToBeDead || app.thread == null) {
   2452                 // We already have the app running, or are waiting for it to
   2453                 // come up (we have a pid but not yet its thread), so keep it.
   2454                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2455                 // If this is a new package in the process, add the package to the list
   2456                 app.addPackage(info.packageName, mProcessStats);
   2457                 return app;
   2458             }
   2459 
   2460             // An application record is attached to a previous process,
   2461             // clean it up now.
   2462             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2463             handleAppDiedLocked(app, true, true);
   2464         }
   2465 
   2466         String hostingNameStr = hostingName != null
   2467                 ? hostingName.flattenToShortString() : null;
   2468 
   2469         if (!isolated) {
   2470             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   2471                 // If we are in the background, then check to see if this process
   2472                 // is bad.  If so, we will just silently fail.
   2473                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2474                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   2475                             + "/" + info.processName);
   2476                     return null;
   2477                 }
   2478             } else {
   2479                 // When the user is explicitly starting a process, then clear its
   2480                 // crash count so that we won't make it bad until they see at
   2481                 // least one crash dialog again, and make the process good again
   2482                 // if it had been bad.
   2483                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   2484                         + "/" + info.processName);
   2485                 mProcessCrashTimes.remove(info.processName, info.uid);
   2486                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2487                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2488                             UserHandle.getUserId(info.uid), info.uid,
   2489                             info.processName);
   2490                     mBadProcesses.remove(info.processName, info.uid);
   2491                     if (app != null) {
   2492                         app.bad = false;
   2493                     }
   2494                 }
   2495             }
   2496         }
   2497 
   2498         if (app == null) {
   2499             app = newProcessRecordLocked(info, processName, isolated);
   2500             if (app == null) {
   2501                 Slog.w(TAG, "Failed making new process record for "
   2502                         + processName + "/" + info.uid + " isolated=" + isolated);
   2503                 return null;
   2504             }
   2505             mProcessNames.put(processName, app.uid, app);
   2506             if (isolated) {
   2507                 mIsolatedProcesses.put(app.uid, app);
   2508             }
   2509         } else {
   2510             // If this is a new package in the process, add the package to the list
   2511             app.addPackage(info.packageName, mProcessStats);
   2512         }
   2513 
   2514         // If the system is not ready yet, then hold off on starting this
   2515         // process until it is.
   2516         if (!mProcessesReady
   2517                 && !isAllowedWhileBooting(info)
   2518                 && !allowWhileBooting) {
   2519             if (!mProcessesOnHold.contains(app)) {
   2520                 mProcessesOnHold.add(app);
   2521             }
   2522             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2523             return app;
   2524         }
   2525 
   2526         startProcessLocked(app, hostingType, hostingNameStr);
   2527         return (app.pid != 0) ? app : null;
   2528     }
   2529 
   2530     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2531         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2532     }
   2533 
   2534     private final void startProcessLocked(ProcessRecord app,
   2535             String hostingType, String hostingNameStr) {
   2536         if (app.pid > 0 && app.pid != MY_PID) {
   2537             synchronized (mPidsSelfLocked) {
   2538                 mPidsSelfLocked.remove(app.pid);
   2539                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2540             }
   2541             app.setPid(0);
   2542         }
   2543 
   2544         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2545                 "startProcessLocked removing on hold: " + app);
   2546         mProcessesOnHold.remove(app);
   2547 
   2548         updateCpuStats();
   2549 
   2550         try {
   2551             int uid = app.uid;
   2552 
   2553             int[] gids = null;
   2554             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2555             if (!app.isolated) {
   2556                 int[] permGids = null;
   2557                 try {
   2558                     final PackageManager pm = mContext.getPackageManager();
   2559                     permGids = pm.getPackageGids(app.info.packageName);
   2560 
   2561                     if (Environment.isExternalStorageEmulated()) {
   2562                         if (pm.checkPermission(
   2563                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2564                                 app.info.packageName) == PERMISSION_GRANTED) {
   2565                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2566                         } else {
   2567                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2568                         }
   2569                     }
   2570                 } catch (PackageManager.NameNotFoundException e) {
   2571                     Slog.w(TAG, "Unable to retrieve gids", e);
   2572                 }
   2573 
   2574                 /*
   2575                  * Add shared application GID so applications can share some
   2576                  * resources like shared libraries
   2577                  */
   2578                 if (permGids == null) {
   2579                     gids = new int[1];
   2580                 } else {
   2581                     gids = new int[permGids.length + 1];
   2582                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
   2583                 }
   2584                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2585             }
   2586             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2587                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2588                         && mTopComponent != null
   2589                         && app.processName.equals(mTopComponent.getPackageName())) {
   2590                     uid = 0;
   2591                 }
   2592                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2593                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2594                     uid = 0;
   2595                 }
   2596             }
   2597             int debugFlags = 0;
   2598             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2599                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2600                 // Also turn on CheckJNI for debuggable apps. It's quite
   2601                 // awkward to turn on otherwise.
   2602                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2603             }
   2604             // Run the app in safe mode if its manifest requests so or the
   2605             // system is booted in safe mode.
   2606             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2607                 Zygote.systemInSafeMode == true) {
   2608                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2609             }
   2610             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2611                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2612             }
   2613             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2614                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2615             }
   2616             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2617                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2618             }
   2619 
   2620             // Start the process.  It will either succeed and return a result containing
   2621             // the PID of the new process, or else throw a RuntimeException.
   2622             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   2623                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   2624                     app.info.targetSdkVersion, app.info.seinfo, null);
   2625 
   2626             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
   2627             synchronized (bs) {
   2628                 if (bs.isOnBattery()) {
   2629                     app.batteryStats.incStartsLocked();
   2630                 }
   2631             }
   2632 
   2633             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   2634                     UserHandle.getUserId(uid), startResult.pid, uid,
   2635                     app.processName, hostingType,
   2636                     hostingNameStr != null ? hostingNameStr : "");
   2637 
   2638             if (app.persistent) {
   2639                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   2640             }
   2641 
   2642             StringBuilder buf = mStringBuilder;
   2643             buf.setLength(0);
   2644             buf.append("Start proc ");
   2645             buf.append(app.processName);
   2646             buf.append(" for ");
   2647             buf.append(hostingType);
   2648             if (hostingNameStr != null) {
   2649                 buf.append(" ");
   2650                 buf.append(hostingNameStr);
   2651             }
   2652             buf.append(": pid=");
   2653             buf.append(startResult.pid);
   2654             buf.append(" uid=");
   2655             buf.append(uid);
   2656             buf.append(" gids={");
   2657             if (gids != null) {
   2658                 for (int gi=0; gi<gids.length; gi++) {
   2659                     if (gi != 0) buf.append(", ");
   2660                     buf.append(gids[gi]);
   2661 
   2662                 }
   2663             }
   2664             buf.append("}");
   2665             Slog.i(TAG, buf.toString());
   2666             app.setPid(startResult.pid);
   2667             app.usingWrapper = startResult.usingWrapper;
   2668             app.removed = false;
   2669             synchronized (mPidsSelfLocked) {
   2670                 this.mPidsSelfLocked.put(startResult.pid, app);
   2671                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2672                 msg.obj = app;
   2673                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2674                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2675             }
   2676         } catch (RuntimeException e) {
   2677             // XXX do better error recovery.
   2678             app.setPid(0);
   2679             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2680         }
   2681     }
   2682 
   2683     void updateUsageStats(ActivityRecord component, boolean resumed) {
   2684         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
   2685         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2686         if (resumed) {
   2687             mUsageStatsService.noteResumeComponent(component.realActivity);
   2688             synchronized (stats) {
   2689                 stats.noteActivityResumedLocked(component.app.uid);
   2690             }
   2691         } else {
   2692             mUsageStatsService.notePauseComponent(component.realActivity);
   2693             synchronized (stats) {
   2694                 stats.noteActivityPausedLocked(component.app.uid);
   2695             }
   2696         }
   2697     }
   2698 
   2699     Intent getHomeIntent() {
   2700         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   2701         intent.setComponent(mTopComponent);
   2702         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2703             intent.addCategory(Intent.CATEGORY_HOME);
   2704         }
   2705         return intent;
   2706     }
   2707 
   2708     boolean startHomeActivityLocked(int userId) {
   2709         if (mHeadless) {
   2710             // Added because none of the other calls to ensureBootCompleted seem to fire
   2711             // when running headless.
   2712             ensureBootCompleted();
   2713             return false;
   2714         }
   2715 
   2716         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2717                 && mTopAction == null) {
   2718             // We are running in factory test mode, but unable to find
   2719             // the factory test app, so just sit around displaying the
   2720             // error message and don't try to start anything.
   2721             return false;
   2722         }
   2723         Intent intent = getHomeIntent();
   2724         ActivityInfo aInfo =
   2725             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   2726         if (aInfo != null) {
   2727             intent.setComponent(new ComponentName(
   2728                     aInfo.applicationInfo.packageName, aInfo.name));
   2729             // Don't do this if the home app is currently being
   2730             // instrumented.
   2731             aInfo = new ActivityInfo(aInfo);
   2732             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   2733             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2734                     aInfo.applicationInfo.uid, true);
   2735             if (app == null || app.instrumentationClass == null) {
   2736                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2737                 mStackSupervisor.startHomeActivity(intent, aInfo);
   2738             }
   2739         }
   2740 
   2741         return true;
   2742     }
   2743 
   2744     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   2745         ActivityInfo ai = null;
   2746         ComponentName comp = intent.getComponent();
   2747         try {
   2748             if (comp != null) {
   2749                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   2750             } else {
   2751                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   2752                         intent,
   2753                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   2754                             flags, userId);
   2755 
   2756                 if (info != null) {
   2757                     ai = info.activityInfo;
   2758                 }
   2759             }
   2760         } catch (RemoteException e) {
   2761             // ignore
   2762         }
   2763 
   2764         return ai;
   2765     }
   2766 
   2767     /**
   2768      * Starts the "new version setup screen" if appropriate.
   2769      */
   2770     void startSetupActivityLocked() {
   2771         // Only do this once per boot.
   2772         if (mCheckedForSetup) {
   2773             return;
   2774         }
   2775 
   2776         // We will show this screen if the current one is a different
   2777         // version than the last one shown, and we are not running in
   2778         // low-level factory test mode.
   2779         final ContentResolver resolver = mContext.getContentResolver();
   2780         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2781                 Settings.Global.getInt(resolver,
   2782                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   2783             mCheckedForSetup = true;
   2784 
   2785             // See if we should be showing the platform update setup UI.
   2786             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2787             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2788                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2789 
   2790             // We don't allow third party apps to replace this.
   2791             ResolveInfo ri = null;
   2792             for (int i=0; ris != null && i<ris.size(); i++) {
   2793                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2794                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2795                     ri = ris.get(i);
   2796                     break;
   2797                 }
   2798             }
   2799 
   2800             if (ri != null) {
   2801                 String vers = ri.activityInfo.metaData != null
   2802                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2803                         : null;
   2804                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2805                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2806                             Intent.METADATA_SETUP_VERSION);
   2807                 }
   2808                 String lastVers = Settings.Secure.getString(
   2809                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2810                 if (vers != null && !vers.equals(lastVers)) {
   2811                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2812                     intent.setComponent(new ComponentName(
   2813                             ri.activityInfo.packageName, ri.activityInfo.name));
   2814                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
   2815                             null, null, 0, 0, 0, null, 0, null, false, null);
   2816                 }
   2817             }
   2818         }
   2819     }
   2820 
   2821     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2822         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2823     }
   2824 
   2825     void enforceNotIsolatedCaller(String caller) {
   2826         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   2827             throw new SecurityException("Isolated process not allowed to call " + caller);
   2828         }
   2829     }
   2830 
   2831     @Override
   2832     public int getFrontActivityScreenCompatMode() {
   2833         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   2834         synchronized (this) {
   2835             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2836         }
   2837     }
   2838 
   2839     @Override
   2840     public void setFrontActivityScreenCompatMode(int mode) {
   2841         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2842                 "setFrontActivityScreenCompatMode");
   2843         synchronized (this) {
   2844             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2845         }
   2846     }
   2847 
   2848     @Override
   2849     public int getPackageScreenCompatMode(String packageName) {
   2850         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   2851         synchronized (this) {
   2852             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   2853         }
   2854     }
   2855 
   2856     @Override
   2857     public void setPackageScreenCompatMode(String packageName, int mode) {
   2858         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2859                 "setPackageScreenCompatMode");
   2860         synchronized (this) {
   2861             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   2862         }
   2863     }
   2864 
   2865     @Override
   2866     public boolean getPackageAskScreenCompat(String packageName) {
   2867         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   2868         synchronized (this) {
   2869             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   2870         }
   2871     }
   2872 
   2873     @Override
   2874     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   2875         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2876                 "setPackageAskScreenCompat");
   2877         synchronized (this) {
   2878             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   2879         }
   2880     }
   2881 
   2882     private void dispatchProcessesChanged() {
   2883         int N;
   2884         synchronized (this) {
   2885             N = mPendingProcessChanges.size();
   2886             if (mActiveProcessChanges.length < N) {
   2887                 mActiveProcessChanges = new ProcessChangeItem[N];
   2888             }
   2889             mPendingProcessChanges.toArray(mActiveProcessChanges);
   2890             mAvailProcessChanges.addAll(mPendingProcessChanges);
   2891             mPendingProcessChanges.clear();
   2892             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   2893         }
   2894 
   2895         int i = mProcessObservers.beginBroadcast();
   2896         while (i > 0) {
   2897             i--;
   2898             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2899             if (observer != null) {
   2900                 try {
   2901                     for (int j=0; j<N; j++) {
   2902                         ProcessChangeItem item = mActiveProcessChanges[j];
   2903                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   2904                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   2905                                     + item.pid + " uid=" + item.uid + ": "
   2906                                     + item.foregroundActivities);
   2907                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   2908                                     item.foregroundActivities);
   2909                         }
   2910                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
   2911                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
   2912                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
   2913                             observer.onImportanceChanged(item.pid, item.uid,
   2914                                     item.importance);
   2915                         }
   2916                     }
   2917                 } catch (RemoteException e) {
   2918                 }
   2919             }
   2920         }
   2921         mProcessObservers.finishBroadcast();
   2922     }
   2923 
   2924     private void dispatchProcessDied(int pid, int uid) {
   2925         int i = mProcessObservers.beginBroadcast();
   2926         while (i > 0) {
   2927             i--;
   2928             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   2929             if (observer != null) {
   2930                 try {
   2931                     observer.onProcessDied(pid, uid);
   2932                 } catch (RemoteException e) {
   2933                 }
   2934             }
   2935         }
   2936         mProcessObservers.finishBroadcast();
   2937     }
   2938 
   2939     final void doPendingActivityLaunchesLocked(boolean doResume) {
   2940         final int N = mPendingActivityLaunches.size();
   2941         if (N <= 0) {
   2942             return;
   2943         }
   2944         for (int i=0; i<N; i++) {
   2945             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   2946             mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
   2947                     doResume && i == (N-1), null);
   2948         }
   2949         mPendingActivityLaunches.clear();
   2950     }
   2951 
   2952     @Override
   2953     public final int startActivity(IApplicationThread caller, String callingPackage,
   2954             Intent intent, String resolvedType, IBinder resultTo,
   2955             String resultWho, int requestCode, int startFlags,
   2956             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
   2957         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   2958                 resultWho, requestCode,
   2959                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
   2960     }
   2961 
   2962     @Override
   2963     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   2964             Intent intent, String resolvedType, IBinder resultTo,
   2965             String resultWho, int requestCode, int startFlags,
   2966             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2967         enforceNotIsolatedCaller("startActivity");
   2968         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2969                 false, true, "startActivity", null);
   2970         // TODO: Switch to user app stacks here.
   2971         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   2972                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2973                 null, null, options, userId);
   2974     }
   2975 
   2976     @Override
   2977     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   2978             Intent intent, String resolvedType, IBinder resultTo,
   2979             String resultWho, int requestCode, int startFlags, String profileFile,
   2980             ParcelFileDescriptor profileFd, Bundle options, int userId) {
   2981         enforceNotIsolatedCaller("startActivityAndWait");
   2982         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2983                 false, true, "startActivityAndWait", null);
   2984         WaitResult res = new WaitResult();
   2985         // TODO: Switch to user app stacks here.
   2986         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   2987                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   2988                 res, null, options, UserHandle.getCallingUserId());
   2989         return res;
   2990     }
   2991 
   2992     @Override
   2993     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   2994             Intent intent, String resolvedType, IBinder resultTo,
   2995             String resultWho, int requestCode, int startFlags, Configuration config,
   2996             Bundle options, int userId) {
   2997         enforceNotIsolatedCaller("startActivityWithConfig");
   2998         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   2999                 false, true, "startActivityWithConfig", null);
   3000         // TODO: Switch to user app stacks here.
   3001         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3002                 resolvedType, resultTo, resultWho, requestCode, startFlags,
   3003                 null, null, null, config, options, userId);
   3004         return ret;
   3005     }
   3006 
   3007     @Override
   3008     public int startActivityIntentSender(IApplicationThread caller,
   3009             IntentSender intent, Intent fillInIntent, String resolvedType,
   3010             IBinder resultTo, String resultWho, int requestCode,
   3011             int flagsMask, int flagsValues, Bundle options) {
   3012         enforceNotIsolatedCaller("startActivityIntentSender");
   3013         // Refuse possible leaked file descriptors
   3014         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3015             throw new IllegalArgumentException("File descriptors passed in Intent");
   3016         }
   3017 
   3018         IIntentSender sender = intent.getTarget();
   3019         if (!(sender instanceof PendingIntentRecord)) {
   3020             throw new IllegalArgumentException("Bad PendingIntent object");
   3021         }
   3022 
   3023         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3024 
   3025         synchronized (this) {
   3026             // If this is coming from the currently resumed activity, it is
   3027             // effectively saying that app switches are allowed at this point.
   3028             final ActivityStack stack = getFocusedStack();
   3029             if (stack.mResumedActivity != null &&
   3030                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   3031                 mAppSwitchesAllowedTime = 0;
   3032             }
   3033         }
   3034         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   3035                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
   3036         return ret;
   3037     }
   3038 
   3039     @Override
   3040     public boolean startNextMatchingActivity(IBinder callingActivity,
   3041             Intent intent, Bundle options) {
   3042         // Refuse possible leaked file descriptors
   3043         if (intent != null && intent.hasFileDescriptors() == true) {
   3044             throw new IllegalArgumentException("File descriptors passed in Intent");
   3045         }
   3046 
   3047         synchronized (this) {
   3048             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   3049             if (r == null) {
   3050                 ActivityOptions.abort(options);
   3051                 return false;
   3052             }
   3053             if (r.app == null || r.app.thread == null) {
   3054                 // The caller is not running...  d'oh!
   3055                 ActivityOptions.abort(options);
   3056                 return false;
   3057             }
   3058             intent = new Intent(intent);
   3059             // The caller is not allowed to change the data.
   3060             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3061             // And we are resetting to find the next component...
   3062             intent.setComponent(null);
   3063 
   3064             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3065 
   3066             ActivityInfo aInfo = null;
   3067             try {
   3068                 List<ResolveInfo> resolves =
   3069                     AppGlobals.getPackageManager().queryIntentActivities(
   3070                             intent, r.resolvedType,
   3071                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   3072                             UserHandle.getCallingUserId());
   3073 
   3074                 // Look for the original activity in the list...
   3075                 final int N = resolves != null ? resolves.size() : 0;
   3076                 for (int i=0; i<N; i++) {
   3077                     ResolveInfo rInfo = resolves.get(i);
   3078                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3079                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3080                         // We found the current one...  the next matching is
   3081                         // after it.
   3082                         i++;
   3083                         if (i<N) {
   3084                             aInfo = resolves.get(i).activityInfo;
   3085                         }
   3086                         if (debug) {
   3087                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   3088                                     + "/" + r.info.name);
   3089                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
   3090                                     + "/" + aInfo.name);
   3091                         }
   3092                         break;
   3093                     }
   3094                 }
   3095             } catch (RemoteException e) {
   3096             }
   3097 
   3098             if (aInfo == null) {
   3099                 // Nobody who is next!
   3100                 ActivityOptions.abort(options);
   3101                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   3102                 return false;
   3103             }
   3104 
   3105             intent.setComponent(new ComponentName(
   3106                     aInfo.applicationInfo.packageName, aInfo.name));
   3107             intent.setFlags(intent.getFlags()&~(
   3108                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3109                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3110                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3111                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3112 
   3113             // Okay now we need to start the new activity, replacing the
   3114             // currently running activity.  This is a little tricky because
   3115             // we want to start the new one as if the current one is finished,
   3116             // but not finish the current one first so that there is no flicker.
   3117             // And thus...
   3118             final boolean wasFinishing = r.finishing;
   3119             r.finishing = true;
   3120 
   3121             // Propagate reply information over to the new activity.
   3122             final ActivityRecord resultTo = r.resultTo;
   3123             final String resultWho = r.resultWho;
   3124             final int requestCode = r.requestCode;
   3125             r.resultTo = null;
   3126             if (resultTo != null) {
   3127                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3128             }
   3129 
   3130             final long origId = Binder.clearCallingIdentity();
   3131             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
   3132                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
   3133                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
   3134                     options, false, null);
   3135             Binder.restoreCallingIdentity(origId);
   3136 
   3137             r.finishing = wasFinishing;
   3138             if (res != ActivityManager.START_SUCCESS) {
   3139                 return false;
   3140             }
   3141             return true;
   3142         }
   3143     }
   3144 
   3145     final int startActivityInPackage(int uid, String callingPackage,
   3146             Intent intent, String resolvedType, IBinder resultTo,
   3147             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
   3148 
   3149         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3150                 false, true, "startActivityInPackage", null);
   3151 
   3152         // TODO: Switch to user app stacks here.
   3153         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
   3154                 resultTo, resultWho, requestCode, startFlags,
   3155                 null, null, null, null, options, userId);
   3156         return ret;
   3157     }
   3158 
   3159     @Override
   3160     public final int startActivities(IApplicationThread caller, String callingPackage,
   3161             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   3162             int userId) {
   3163         enforceNotIsolatedCaller("startActivities");
   3164         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3165                 false, true, "startActivity", null);
   3166         // TODO: Switch to user app stacks here.
   3167         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
   3168                 resolvedTypes, resultTo, options, userId);
   3169         return ret;
   3170     }
   3171 
   3172     final int startActivitiesInPackage(int uid, String callingPackage,
   3173             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   3174             Bundle options, int userId) {
   3175 
   3176         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3177                 false, true, "startActivityInPackage", null);
   3178         // TODO: Switch to user app stacks here.
   3179         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   3180                 resultTo, options, userId);
   3181         return ret;
   3182     }
   3183 
   3184     final void addRecentTaskLocked(TaskRecord task) {
   3185         int N = mRecentTasks.size();
   3186         // Quick case: check if the top-most recent task is the same.
   3187         if (N > 0 && mRecentTasks.get(0) == task) {
   3188             return;
   3189         }
   3190         // Remove any existing entries that are the same kind of task.
   3191         for (int i=0; i<N; i++) {
   3192             TaskRecord tr = mRecentTasks.get(i);
   3193             if (task.userId == tr.userId
   3194                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
   3195                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
   3196                 tr.disposeThumbnail();
   3197                 mRecentTasks.remove(i);
   3198                 i--;
   3199                 N--;
   3200                 if (task.intent == null) {
   3201                     // If the new recent task we are adding is not fully
   3202                     // specified, then replace it with the existing recent task.
   3203                     task = tr;
   3204                 }
   3205             }
   3206         }
   3207         if (N >= MAX_RECENT_TASKS) {
   3208             mRecentTasks.remove(N-1).disposeThumbnail();
   3209         }
   3210         mRecentTasks.add(0, task);
   3211     }
   3212 
   3213     @Override
   3214     public void reportActivityFullyDrawn(IBinder token) {
   3215         synchronized (this) {
   3216             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3217             if (r == null) {
   3218                 return;
   3219             }
   3220             r.reportFullyDrawnLocked();
   3221         }
   3222     }
   3223 
   3224     @Override
   3225     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   3226         synchronized (this) {
   3227             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3228             if (r == null) {
   3229                 return;
   3230             }
   3231             final long origId = Binder.clearCallingIdentity();
   3232             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   3233             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   3234                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   3235             if (config != null) {
   3236                 r.frozenBeforeDestroy = true;
   3237                 if (!updateConfigurationLocked(config, r, false, false)) {
   3238                     mStackSupervisor.resumeTopActivitiesLocked();
   3239                 }
   3240             }
   3241             Binder.restoreCallingIdentity(origId);
   3242         }
   3243     }
   3244 
   3245     @Override
   3246     public int getRequestedOrientation(IBinder token) {
   3247         synchronized (this) {
   3248             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3249             if (r == null) {
   3250                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   3251             }
   3252             return mWindowManager.getAppOrientation(r.appToken);
   3253         }
   3254     }
   3255 
   3256     /**
   3257      * This is the internal entry point for handling Activity.finish().
   3258      *
   3259      * @param token The Binder token referencing the Activity we want to finish.
   3260      * @param resultCode Result code, if any, from this Activity.
   3261      * @param resultData Result data (Intent), if any, from this Activity.
   3262      *
   3263      * @return Returns true if the activity successfully finished, or false if it is still running.
   3264      */
   3265     @Override
   3266     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   3267         // Refuse possible leaked file descriptors
   3268         if (resultData != null && resultData.hasFileDescriptors() == true) {
   3269             throw new IllegalArgumentException("File descriptors passed in Intent");
   3270         }
   3271 
   3272         synchronized(this) {
   3273             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3274             if (r == null) {
   3275                 return true;
   3276             }
   3277             if (mController != null) {
   3278                 // Find the first activity that is not finishing.
   3279                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   3280                 if (next != null) {
   3281                     // ask watcher if this is allowed
   3282                     boolean resumeOK = true;
   3283                     try {
   3284                         resumeOK = mController.activityResuming(next.packageName);
   3285                     } catch (RemoteException e) {
   3286                         mController = null;
   3287                         Watchdog.getInstance().setActivityController(null);
   3288                     }
   3289 
   3290                     if (!resumeOK) {
   3291                         return false;
   3292                     }
   3293                 }
   3294             }
   3295             final long origId = Binder.clearCallingIdentity();
   3296             boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
   3297                     resultData, "app-request", true);
   3298             Binder.restoreCallingIdentity(origId);
   3299             return res;
   3300         }
   3301     }
   3302 
   3303     @Override
   3304     public final void finishHeavyWeightApp() {
   3305         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3306                 != PackageManager.PERMISSION_GRANTED) {
   3307             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   3308                     + Binder.getCallingPid()
   3309                     + ", uid=" + Binder.getCallingUid()
   3310                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3311             Slog.w(TAG, msg);
   3312             throw new SecurityException(msg);
   3313         }
   3314 
   3315         synchronized(this) {
   3316             if (mHeavyWeightProcess == null) {
   3317                 return;
   3318             }
   3319 
   3320             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   3321                     mHeavyWeightProcess.activities);
   3322             for (int i=0; i<activities.size(); i++) {
   3323                 ActivityRecord r = activities.get(i);
   3324                 if (!r.finishing) {
   3325                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   3326                             null, "finish-heavy", true);
   3327                 }
   3328             }
   3329 
   3330             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   3331                     mHeavyWeightProcess.userId, 0));
   3332             mHeavyWeightProcess = null;
   3333         }
   3334     }
   3335 
   3336     @Override
   3337     public void crashApplication(int uid, int initialPid, String packageName,
   3338             String message) {
   3339         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3340                 != PackageManager.PERMISSION_GRANTED) {
   3341             String msg = "Permission Denial: crashApplication() from pid="
   3342                     + Binder.getCallingPid()
   3343                     + ", uid=" + Binder.getCallingUid()
   3344                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3345             Slog.w(TAG, msg);
   3346             throw new SecurityException(msg);
   3347         }
   3348 
   3349         synchronized(this) {
   3350             ProcessRecord proc = null;
   3351 
   3352             // Figure out which process to kill.  We don't trust that initialPid
   3353             // still has any relation to current pids, so must scan through the
   3354             // list.
   3355             synchronized (mPidsSelfLocked) {
   3356                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   3357                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   3358                     if (p.uid != uid) {
   3359                         continue;
   3360                     }
   3361                     if (p.pid == initialPid) {
   3362                         proc = p;
   3363                         break;
   3364                     }
   3365                     if (p.pkgList.containsKey(packageName)) {
   3366                         proc = p;
   3367                     }
   3368                 }
   3369             }
   3370 
   3371             if (proc == null) {
   3372                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   3373                         + " initialPid=" + initialPid
   3374                         + " packageName=" + packageName);
   3375                 return;
   3376             }
   3377 
   3378             if (proc.thread != null) {
   3379                 if (proc.pid == Process.myPid()) {
   3380                     Log.w(TAG, "crashApplication: trying to crash self!");
   3381                     return;
   3382                 }
   3383                 long ident = Binder.clearCallingIdentity();
   3384                 try {
   3385                     proc.thread.scheduleCrash(message);
   3386                 } catch (RemoteException e) {
   3387                 }
   3388                 Binder.restoreCallingIdentity(ident);
   3389             }
   3390         }
   3391     }
   3392 
   3393     @Override
   3394     public final void finishSubActivity(IBinder token, String resultWho,
   3395             int requestCode) {
   3396         synchronized(this) {
   3397             final long origId = Binder.clearCallingIdentity();
   3398             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3399             if (r != null) {
   3400                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   3401             }
   3402             Binder.restoreCallingIdentity(origId);
   3403         }
   3404     }
   3405 
   3406     @Override
   3407     public boolean finishActivityAffinity(IBinder token) {
   3408         synchronized(this) {
   3409             final long origId = Binder.clearCallingIdentity();
   3410             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3411             boolean res = false;
   3412             if (r != null) {
   3413                 res = r.task.stack.finishActivityAffinityLocked(r);
   3414             }
   3415             Binder.restoreCallingIdentity(origId);
   3416             return res;
   3417         }
   3418     }
   3419 
   3420     @Override
   3421     public boolean willActivityBeVisible(IBinder token) {
   3422         synchronized(this) {
   3423             ActivityStack stack = ActivityRecord.getStackLocked(token);
   3424             if (stack != null) {
   3425                 return stack.willActivityBeVisibleLocked(token);
   3426             }
   3427             return false;
   3428         }
   3429     }
   3430 
   3431     @Override
   3432     public void overridePendingTransition(IBinder token, String packageName,
   3433             int enterAnim, int exitAnim) {
   3434         synchronized(this) {
   3435             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   3436             if (self == null) {
   3437                 return;
   3438             }
   3439 
   3440             final long origId = Binder.clearCallingIdentity();
   3441 
   3442             if (self.state == ActivityState.RESUMED
   3443                     || self.state == ActivityState.PAUSING) {
   3444                 mWindowManager.overridePendingAppTransition(packageName,
   3445                         enterAnim, exitAnim, null);
   3446             }
   3447 
   3448             Binder.restoreCallingIdentity(origId);
   3449         }
   3450     }
   3451 
   3452     /**
   3453      * Main function for removing an existing process from the activity manager
   3454      * as a result of that process going away.  Clears out all connections
   3455      * to the process.
   3456      */
   3457     private final void handleAppDiedLocked(ProcessRecord app,
   3458             boolean restarting, boolean allowRestart) {
   3459         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   3460         if (!restarting) {
   3461             removeLruProcessLocked(app);
   3462         }
   3463 
   3464         if (mProfileProc == app) {
   3465             clearProfilerLocked();
   3466         }
   3467 
   3468         // Remove this application's activities from active lists.
   3469         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   3470 
   3471         app.activities.clear();
   3472 
   3473         if (app.instrumentationClass != null) {
   3474             Slog.w(TAG, "Crash of app " + app.processName
   3475                   + " running instrumentation " + app.instrumentationClass);
   3476             Bundle info = new Bundle();
   3477             info.putString("shortMsg", "Process crashed.");
   3478             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   3479         }
   3480 
   3481         if (!restarting) {
   3482             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
   3483                 // If there was nothing to resume, and we are not already
   3484                 // restarting this process, but there is a visible activity that
   3485                 // is hosted by the process...  then make sure all visible
   3486                 // activities are running, taking care of restarting this
   3487                 // process.
   3488                 if (hasVisibleActivities) {
   3489                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   3490                 }
   3491             }
   3492         }
   3493     }
   3494 
   3495     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   3496         IBinder threadBinder = thread.asBinder();
   3497         // Find the application record.
   3498         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3499             ProcessRecord rec = mLruProcesses.get(i);
   3500             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   3501                 return i;
   3502             }
   3503         }
   3504         return -1;
   3505     }
   3506 
   3507     final ProcessRecord getRecordForAppLocked(
   3508             IApplicationThread thread) {
   3509         if (thread == null) {
   3510             return null;
   3511         }
   3512 
   3513         int appIndex = getLRURecordIndexForAppLocked(thread);
   3514         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   3515     }
   3516 
   3517     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   3518         // If there are no longer any background processes running,
   3519         // and the app that died was not running instrumentation,
   3520         // then tell everyone we are now low on memory.
   3521         boolean haveBg = false;
   3522         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3523             ProcessRecord rec = mLruProcesses.get(i);
   3524             if (rec.thread != null
   3525                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   3526                 haveBg = true;
   3527                 break;
   3528             }
   3529         }
   3530 
   3531         if (!haveBg) {
   3532             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   3533             if (doReport) {
   3534                 long now = SystemClock.uptimeMillis();
   3535                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   3536                     doReport = false;
   3537                 } else {
   3538                     mLastMemUsageReportTime = now;
   3539                 }
   3540             }
   3541             final ArrayList<ProcessMemInfo> memInfos
   3542                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   3543             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   3544             long now = SystemClock.uptimeMillis();
   3545             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3546                 ProcessRecord rec = mLruProcesses.get(i);
   3547                 if (rec == dyingProc || rec.thread == null) {
   3548                     continue;
   3549                 }
   3550                 if (doReport) {
   3551                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   3552                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   3553                 }
   3554                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   3555                     // The low memory report is overriding any current
   3556                     // state for a GC request.  Make sure to do
   3557                     // heavy/important/visible/foreground processes first.
   3558                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   3559                         rec.lastRequestedGc = 0;
   3560                     } else {
   3561                         rec.lastRequestedGc = rec.lastLowMemory;
   3562                     }
   3563                     rec.reportLowMemory = true;
   3564                     rec.lastLowMemory = now;
   3565                     mProcessesToGc.remove(rec);
   3566                     addProcessToGcListLocked(rec);
   3567                 }
   3568             }
   3569             if (doReport) {
   3570                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   3571                 mHandler.sendMessage(msg);
   3572             }
   3573             scheduleAppGcsLocked();
   3574         }
   3575     }
   3576 
   3577     final void appDiedLocked(ProcessRecord app, int pid,
   3578             IApplicationThread thread) {
   3579 
   3580         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3581         synchronized (stats) {
   3582             stats.noteProcessDiedLocked(app.info.uid, pid);
   3583         }
   3584 
   3585         // Clean up already done if the process has been re-started.
   3586         if (app.pid == pid && app.thread != null &&
   3587                 app.thread.asBinder() == thread.asBinder()) {
   3588             boolean doLowMem = app.instrumentationClass == null;
   3589             boolean doOomAdj = doLowMem;
   3590             if (!app.killedByAm) {
   3591                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3592                         + ") has died.");
   3593                 mAllowLowerMemLevel = true;
   3594             } else {
   3595                 // Note that we always want to do oom adj to update our state with the
   3596                 // new number of procs.
   3597                 mAllowLowerMemLevel = false;
   3598                 doLowMem = false;
   3599             }
   3600             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3601             if (DEBUG_CLEANUP) Slog.v(
   3602                 TAG, "Dying app: " + app + ", pid: " + pid
   3603                 + ", thread: " + thread.asBinder());
   3604             handleAppDiedLocked(app, false, true);
   3605 
   3606             if (doOomAdj) {
   3607                 updateOomAdjLocked();
   3608             }
   3609             if (doLowMem) {
   3610                 doLowMemReportIfNeededLocked(app);
   3611             }
   3612         } else if (app.pid != pid) {
   3613             // A new process has already been started.
   3614             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3615                     + ") has died and restarted (pid " + app.pid + ").");
   3616             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3617         } else if (DEBUG_PROCESSES) {
   3618             Slog.d(TAG, "Received spurious death notification for thread "
   3619                     + thread.asBinder());
   3620         }
   3621     }
   3622 
   3623     /**
   3624      * If a stack trace dump file is configured, dump process stack traces.
   3625      * @param clearTraces causes the dump file to be erased prior to the new
   3626      *    traces being written, if true; when false, the new traces will be
   3627      *    appended to any existing file content.
   3628      * @param firstPids of dalvik VM processes to dump stack traces for first
   3629      * @param lastPids of dalvik VM processes to dump stack traces for last
   3630      * @param nativeProcs optional list of native process names to dump stack crawls
   3631      * @return file containing stack traces, or null if no dump file is configured
   3632      */
   3633     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   3634             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3635         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3636         if (tracesPath == null || tracesPath.length() == 0) {
   3637             return null;
   3638         }
   3639 
   3640         File tracesFile = new File(tracesPath);
   3641         try {
   3642             File tracesDir = tracesFile.getParentFile();
   3643             if (!tracesDir.exists()) {
   3644                 tracesFile.mkdirs();
   3645                 if (!SELinux.restorecon(tracesDir)) {
   3646                     return null;
   3647                 }
   3648             }
   3649             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3650 
   3651             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   3652             tracesFile.createNewFile();
   3653             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3654         } catch (IOException e) {
   3655             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   3656             return null;
   3657         }
   3658 
   3659         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   3660         return tracesFile;
   3661     }
   3662 
   3663     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   3664             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3665         // Use a FileObserver to detect when traces finish writing.
   3666         // The order of traces is considered important to maintain for legibility.
   3667         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   3668             @Override
   3669             public synchronized void onEvent(int event, String path) { notify(); }
   3670         };
   3671 
   3672         try {
   3673             observer.startWatching();
   3674 
   3675             // First collect all of the stacks of the most important pids.
   3676             if (firstPids != null) {
   3677                 try {
   3678                     int num = firstPids.size();
   3679                     for (int i = 0; i < num; i++) {
   3680                         synchronized (observer) {
   3681                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   3682                             observer.wait(200);  // Wait for write-close, give up after 200msec
   3683                         }
   3684                     }
   3685                 } catch (InterruptedException e) {
   3686                     Log.wtf(TAG, e);
   3687                 }
   3688             }
   3689 
   3690             // Next measure CPU usage.
   3691             if (processCpuTracker != null) {
   3692                 processCpuTracker.init();
   3693                 System.gc();
   3694                 processCpuTracker.update();
   3695                 try {
   3696                     synchronized (processCpuTracker) {
   3697                         processCpuTracker.wait(500); // measure over 1/2 second.
   3698                     }
   3699                 } catch (InterruptedException e) {
   3700                 }
   3701                 processCpuTracker.update();
   3702 
   3703                 // We'll take the stack crawls of just the top apps using CPU.
   3704                 final int N = processCpuTracker.countWorkingStats();
   3705                 int numProcs = 0;
   3706                 for (int i=0; i<N && numProcs<5; i++) {
   3707                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   3708                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   3709                         numProcs++;
   3710                         try {
   3711                             synchronized (observer) {
   3712                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   3713                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   3714                             }
   3715                         } catch (InterruptedException e) {
   3716                             Log.wtf(TAG, e);
   3717                         }
   3718 
   3719                     }
   3720                 }
   3721             }
   3722 
   3723         } finally {
   3724             observer.stopWatching();
   3725         }
   3726 
   3727         if (nativeProcs != null) {
   3728             int[] pids = Process.getPidsForCommands(nativeProcs);
   3729             if (pids != null) {
   3730                 for (int pid : pids) {
   3731                     Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   3732                 }
   3733             }
   3734         }
   3735     }
   3736 
   3737     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   3738         if (true || IS_USER_BUILD) {
   3739             return;
   3740         }
   3741         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3742         if (tracesPath == null || tracesPath.length() == 0) {
   3743             return;
   3744         }
   3745 
   3746         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3747         StrictMode.allowThreadDiskWrites();
   3748         try {
   3749             final File tracesFile = new File(tracesPath);
   3750             final File tracesDir = tracesFile.getParentFile();
   3751             final File tracesTmp = new File(tracesDir, "__tmp__");
   3752             try {
   3753                 if (!tracesDir.exists()) {
   3754                     tracesFile.mkdirs();
   3755                     if (!SELinux.restorecon(tracesDir.getPath())) {
   3756                         return;
   3757                     }
   3758                 }
   3759                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3760 
   3761                 if (tracesFile.exists()) {
   3762                     tracesTmp.delete();
   3763                     tracesFile.renameTo(tracesTmp);
   3764                 }
   3765                 StringBuilder sb = new StringBuilder();
   3766                 Time tobj = new Time();
   3767                 tobj.set(System.currentTimeMillis());
   3768                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3769                 sb.append(": ");
   3770                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3771                 sb.append(" since ");
   3772                 sb.append(msg);
   3773                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3774                 fos.write(sb.toString().getBytes());
   3775                 if (app == null) {
   3776                     fos.write("\n*** No application process!".getBytes());
   3777                 }
   3778                 fos.close();
   3779                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3780             } catch (IOException e) {
   3781                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3782                 return;
   3783             }
   3784 
   3785             if (app != null) {
   3786                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3787                 firstPids.add(app.pid);
   3788                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   3789             }
   3790 
   3791             File lastTracesFile = null;
   3792             File curTracesFile = null;
   3793             for (int i=9; i>=0; i--) {
   3794                 String name = String.format(Locale.US, "slow%02d.txt", i);
   3795                 curTracesFile = new File(tracesDir, name);
   3796                 if (curTracesFile.exists()) {
   3797                     if (lastTracesFile != null) {
   3798                         curTracesFile.renameTo(lastTracesFile);
   3799                     } else {
   3800                         curTracesFile.delete();
   3801                     }
   3802                 }
   3803                 lastTracesFile = curTracesFile;
   3804             }
   3805             tracesFile.renameTo(curTracesFile);
   3806             if (tracesTmp.exists()) {
   3807                 tracesTmp.renameTo(tracesFile);
   3808             }
   3809         } finally {
   3810             StrictMode.setThreadPolicy(oldPolicy);
   3811         }
   3812     }
   3813 
   3814     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3815             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   3816         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3817         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3818 
   3819         if (mController != null) {
   3820             try {
   3821                 // 0 == continue, -1 = kill process immediately
   3822                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3823                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3824             } catch (RemoteException e) {
   3825                 mController = null;
   3826                 Watchdog.getInstance().setActivityController(null);
   3827             }
   3828         }
   3829 
   3830         long anrTime = SystemClock.uptimeMillis();
   3831         if (MONITOR_CPU_USAGE) {
   3832             updateCpuStatsNow();
   3833         }
   3834 
   3835         synchronized (this) {
   3836             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3837             if (mShuttingDown) {
   3838                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3839                 return;
   3840             } else if (app.notResponding) {
   3841                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3842                 return;
   3843             } else if (app.crashing) {
   3844                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3845                 return;
   3846             }
   3847 
   3848             // In case we come through here for the same app before completing
   3849             // this one, mark as anring now so we will bail out.
   3850             app.notResponding = true;
   3851 
   3852             // Log the ANR to the event log.
   3853             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   3854                     app.processName, app.info.flags, annotation);
   3855 
   3856             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   3857             firstPids.add(app.pid);
   3858 
   3859             int parentPid = app.pid;
   3860             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   3861             if (parentPid != app.pid) firstPids.add(parentPid);
   3862 
   3863             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   3864 
   3865             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   3866                 ProcessRecord r = mLruProcesses.get(i);
   3867                 if (r != null && r.thread != null) {
   3868                     int pid = r.pid;
   3869                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   3870                         if (r.persistent) {
   3871                             firstPids.add(pid);
   3872                         } else {
   3873                             lastPids.put(pid, Boolean.TRUE);
   3874                         }
   3875                     }
   3876                 }
   3877             }
   3878         }
   3879 
   3880         // Log the ANR to the main log.
   3881         StringBuilder info = new StringBuilder();
   3882         info.setLength(0);
   3883         info.append("ANR in ").append(app.processName);
   3884         if (activity != null && activity.shortComponentName != null) {
   3885             info.append(" (").append(activity.shortComponentName).append(")");
   3886         }
   3887         info.append("\n");
   3888         info.append("PID: ").append(app.pid).append("\n");
   3889         if (annotation != null) {
   3890             info.append("Reason: ").append(annotation).append("\n");
   3891         }
   3892         if (parent != null && parent != activity) {
   3893             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   3894         }
   3895 
   3896         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
   3897 
   3898         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, null);
   3899 
   3900         String cpuInfo = null;
   3901         if (MONITOR_CPU_USAGE) {
   3902             updateCpuStatsNow();
   3903             synchronized (mProcessCpuThread) {
   3904                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
   3905             }
   3906             info.append(processCpuTracker.printCurrentLoad());
   3907             info.append(cpuInfo);
   3908         }
   3909 
   3910         info.append(processCpuTracker.printCurrentState(anrTime));
   3911 
   3912         Slog.e(TAG, info.toString());
   3913         if (tracesFile == null) {
   3914             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   3915             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   3916         }
   3917 
   3918         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   3919                 cpuInfo, tracesFile, null);
   3920 
   3921         if (mController != null) {
   3922             try {
   3923                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   3924                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   3925                 if (res != 0) {
   3926                     if (res < 0 && app.pid != MY_PID) {
   3927                         Process.killProcess(app.pid);
   3928                     } else {
   3929                         synchronized (this) {
   3930                             mServices.scheduleServiceTimeoutLocked(app);
   3931                         }
   3932                     }
   3933                     return;
   3934                 }
   3935             } catch (RemoteException e) {
   3936                 mController = null;
   3937                 Watchdog.getInstance().setActivityController(null);
   3938             }
   3939         }
   3940 
   3941         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   3942         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   3943                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   3944 
   3945         synchronized (this) {
   3946             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   3947                 killUnneededProcessLocked(app, "background ANR");
   3948                 return;
   3949             }
   3950 
   3951             // Set the app's notResponding state, and look up the errorReportReceiver
   3952             makeAppNotRespondingLocked(app,
   3953                     activity != null ? activity.shortComponentName : null,
   3954                     annotation != null ? "ANR " + annotation : "ANR",
   3955                     info.toString());
   3956 
   3957             // Bring up the infamous App Not Responding dialog
   3958             Message msg = Message.obtain();
   3959             HashMap<String, Object> map = new HashMap<String, Object>();
   3960             msg.what = SHOW_NOT_RESPONDING_MSG;
   3961             msg.obj = map;
   3962             msg.arg1 = aboveSystem ? 1 : 0;
   3963             map.put("app", app);
   3964             if (activity != null) {
   3965                 map.put("activity", activity);
   3966             }
   3967 
   3968             mHandler.sendMessage(msg);
   3969         }
   3970     }
   3971 
   3972     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   3973         if (!mLaunchWarningShown) {
   3974             mLaunchWarningShown = true;
   3975             mHandler.post(new Runnable() {
   3976                 @Override
   3977                 public void run() {
   3978                     synchronized (ActivityManagerService.this) {
   3979                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   3980                         d.show();
   3981                         mHandler.postDelayed(new Runnable() {
   3982                             @Override
   3983                             public void run() {
   3984                                 synchronized (ActivityManagerService.this) {
   3985                                     d.dismiss();
   3986                                     mLaunchWarningShown = false;
   3987                                 }
   3988                             }
   3989                         }, 4000);
   3990                     }
   3991                 }
   3992             });
   3993         }
   3994     }
   3995 
   3996     @Override
   3997     public boolean clearApplicationUserData(final String packageName,
   3998             final IPackageDataObserver observer, int userId) {
   3999         enforceNotIsolatedCaller("clearApplicationUserData");
   4000         int uid = Binder.getCallingUid();
   4001         int pid = Binder.getCallingPid();
   4002         userId = handleIncomingUser(pid, uid,
   4003                 userId, false, true, "clearApplicationUserData", null);
   4004         long callingId = Binder.clearCallingIdentity();
   4005         try {
   4006             IPackageManager pm = AppGlobals.getPackageManager();
   4007             int pkgUid = -1;
   4008             synchronized(this) {
   4009                 try {
   4010                     pkgUid = pm.getPackageUid(packageName, userId);
   4011                 } catch (RemoteException e) {
   4012                 }
   4013                 if (pkgUid == -1) {
   4014                     Slog.w(TAG, "Invalid packageName: " + packageName);
   4015                     if (observer != null) {
   4016                         try {
   4017                             observer.onRemoveCompleted(packageName, false);
   4018                         } catch (RemoteException e) {
   4019                             Slog.i(TAG, "Observer no longer exists.");
   4020                         }
   4021                     }
   4022                     return false;
   4023                 }
   4024                 if (uid == pkgUid || checkComponentPermission(
   4025                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   4026                         pid, uid, -1, true)
   4027                         == PackageManager.PERMISSION_GRANTED) {
   4028                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   4029                 } else {
   4030                     throw new SecurityException(pid+" does not have permission:"+
   4031                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   4032                                     "for process:"+packageName);
   4033                 }
   4034             }
   4035 
   4036             try {
   4037                 // Clear application user data
   4038                 pm.clearApplicationUserData(packageName, observer, userId);
   4039 
   4040                 // Remove all permissions granted from/to this package
   4041                 removeUriPermissionsForPackageLocked(packageName, userId, true);
   4042 
   4043                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   4044                         Uri.fromParts("package", packageName, null));
   4045                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   4046                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   4047                         null, null, 0, null, null, null, false, false, userId);
   4048             } catch (RemoteException e) {
   4049             }
   4050         } finally {
   4051             Binder.restoreCallingIdentity(callingId);
   4052         }
   4053         return true;
   4054     }
   4055 
   4056     @Override
   4057     public void killBackgroundProcesses(final String packageName, int userId) {
   4058         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   4059                 != PackageManager.PERMISSION_GRANTED &&
   4060                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   4061                         != PackageManager.PERMISSION_GRANTED) {
   4062             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   4063                     + Binder.getCallingPid()
   4064                     + ", uid=" + Binder.getCallingUid()
   4065                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   4066             Slog.w(TAG, msg);
   4067             throw new SecurityException(msg);
   4068         }
   4069 
   4070         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4071                 userId, true, true, "killBackgroundProcesses", null);
   4072         long callingId = Binder.clearCallingIdentity();
   4073         try {
   4074             IPackageManager pm = AppGlobals.getPackageManager();
   4075             synchronized(this) {
   4076                 int appId = -1;
   4077                 try {
   4078                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   4079                 } catch (RemoteException e) {
   4080                 }
   4081                 if (appId == -1) {
   4082                     Slog.w(TAG, "Invalid packageName: " + packageName);
   4083                     return;
   4084                 }
   4085                 killPackageProcessesLocked(packageName, appId, userId,
   4086                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   4087             }
   4088         } finally {
   4089             Binder.restoreCallingIdentity(callingId);
   4090         }
   4091     }
   4092 
   4093     @Override
   4094     public void killAllBackgroundProcesses() {
   4095         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   4096                 != PackageManager.PERMISSION_GRANTED) {
   4097             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   4098                     + Binder.getCallingPid()
   4099                     + ", uid=" + Binder.getCallingUid()
   4100                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   4101             Slog.w(TAG, msg);
   4102             throw new SecurityException(msg);
   4103         }
   4104 
   4105         long callingId = Binder.clearCallingIdentity();
   4106         try {
   4107             synchronized(this) {
   4108                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   4109                 final int NP = mProcessNames.getMap().size();
   4110                 for (int ip=0; ip<NP; ip++) {
   4111                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   4112                     final int NA = apps.size();
   4113                     for (int ia=0; ia<NA; ia++) {
   4114                         ProcessRecord app = apps.valueAt(ia);
   4115                         if (app.persistent) {
   4116                             // we don't kill persistent processes
   4117                             continue;
   4118                         }
   4119                         if (app.removed) {
   4120                             procs.add(app);
   4121                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   4122                             app.removed = true;
   4123                             procs.add(app);
   4124                         }
   4125                     }
   4126                 }
   4127 
   4128                 int N = procs.size();
   4129                 for (int i=0; i<N; i++) {
   4130                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   4131                 }
   4132                 mAllowLowerMemLevel = true;
   4133                 updateOomAdjLocked();
   4134                 doLowMemReportIfNeededLocked(null);
   4135             }
   4136         } finally {
   4137             Binder.restoreCallingIdentity(callingId);
   4138         }
   4139     }
   4140 
   4141     @Override
   4142     public void forceStopPackage(final String packageName, int userId) {
   4143         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4144                 != PackageManager.PERMISSION_GRANTED) {
   4145             String msg = "Permission Denial: forceStopPackage() from pid="
   4146                     + Binder.getCallingPid()
   4147                     + ", uid=" + Binder.getCallingUid()
   4148                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4149             Slog.w(TAG, msg);
   4150             throw new SecurityException(msg);
   4151         }
   4152         final int callingPid = Binder.getCallingPid();
   4153         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
   4154                 userId, true, true, "forceStopPackage", null);
   4155         long callingId = Binder.clearCallingIdentity();
   4156         try {
   4157             IPackageManager pm = AppGlobals.getPackageManager();
   4158             synchronized(this) {
   4159                 int[] users = userId == UserHandle.USER_ALL
   4160                         ? getUsersLocked() : new int[] { userId };
   4161                 for (int user : users) {
   4162                     int pkgUid = -1;
   4163                     try {
   4164                         pkgUid = pm.getPackageUid(packageName, user);
   4165                     } catch (RemoteException e) {
   4166                     }
   4167                     if (pkgUid == -1) {
   4168                         Slog.w(TAG, "Invalid packageName: " + packageName);
   4169                         continue;
   4170                     }
   4171                     try {
   4172                         pm.setPackageStoppedState(packageName, true, user);
   4173                     } catch (RemoteException e) {
   4174                     } catch (IllegalArgumentException e) {
   4175                         Slog.w(TAG, "Failed trying to unstop package "
   4176                                 + packageName + ": " + e);
   4177                     }
   4178                     if (isUserRunningLocked(user, false)) {
   4179                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   4180                     }
   4181                 }
   4182             }
   4183         } finally {
   4184             Binder.restoreCallingIdentity(callingId);
   4185         }
   4186     }
   4187 
   4188     /*
   4189      * The pkg name and app id have to be specified.
   4190      */
   4191     @Override
   4192     public void killApplicationWithAppId(String pkg, int appid, String reason) {
   4193         if (pkg == null) {
   4194             return;
   4195         }
   4196         // Make sure the uid is valid.
   4197         if (appid < 0) {
   4198             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   4199             return;
   4200         }
   4201         int callerUid = Binder.getCallingUid();
   4202         // Only the system server can kill an application
   4203         if (callerUid == Process.SYSTEM_UID) {
   4204             // Post an aysnc message to kill the application
   4205             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   4206             msg.arg1 = appid;
   4207             msg.arg2 = 0;
   4208             Bundle bundle = new Bundle();
   4209             bundle.putString("pkg", pkg);
   4210             bundle.putString("reason", reason);
   4211             msg.obj = bundle;
   4212             mHandler.sendMessage(msg);
   4213         } else {
   4214             throw new SecurityException(callerUid + " cannot kill pkg: " +
   4215                     pkg);
   4216         }
   4217     }
   4218 
   4219     @Override
   4220     public void closeSystemDialogs(String reason) {
   4221         enforceNotIsolatedCaller("closeSystemDialogs");
   4222 
   4223         final int pid = Binder.getCallingPid();
   4224         final int uid = Binder.getCallingUid();
   4225         final long origId = Binder.clearCallingIdentity();
   4226         try {
   4227             synchronized (this) {
   4228                 // Only allow this from foreground processes, so that background
   4229                 // applications can't abuse it to prevent system UI from being shown.
   4230                 if (uid >= Process.FIRST_APPLICATION_UID) {
   4231                     ProcessRecord proc;
   4232                     synchronized (mPidsSelfLocked) {
   4233                         proc = mPidsSelfLocked.get(pid);
   4234                     }
   4235                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   4236                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   4237                                 + " from background process " + proc);
   4238                         return;
   4239                     }
   4240                 }
   4241                 closeSystemDialogsLocked(reason);
   4242             }
   4243         } finally {
   4244             Binder.restoreCallingIdentity(origId);
   4245         }
   4246     }
   4247 
   4248     void closeSystemDialogsLocked(String reason) {
   4249         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   4250         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4251                 | Intent.FLAG_RECEIVER_FOREGROUND);
   4252         if (reason != null) {
   4253             intent.putExtra("reason", reason);
   4254         }
   4255         mWindowManager.closeSystemDialogs(reason);
   4256 
   4257         mStackSupervisor.closeSystemDialogsLocked();
   4258 
   4259         broadcastIntentLocked(null, null, intent, null,
   4260                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   4261                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   4262     }
   4263 
   4264     @Override
   4265     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   4266         enforceNotIsolatedCaller("getProcessMemoryInfo");
   4267         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   4268         for (int i=pids.length-1; i>=0; i--) {
   4269             ProcessRecord proc;
   4270             int oomAdj;
   4271             synchronized (this) {
   4272                 synchronized (mPidsSelfLocked) {
   4273                     proc = mPidsSelfLocked.get(pids[i]);
   4274                     oomAdj = proc != null ? proc.setAdj : 0;
   4275                 }
   4276             }
   4277             infos[i] = new Debug.MemoryInfo();
   4278             Debug.getMemoryInfo(pids[i], infos[i]);
   4279             if (proc != null) {
   4280                 synchronized (this) {
   4281                     if (proc.thread != null && proc.setAdj == oomAdj) {
   4282                         // Record this for posterity if the process has been stable.
   4283                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   4284                                 infos[i].getTotalUss(), false, proc.pkgList);
   4285                     }
   4286                 }
   4287             }
   4288         }
   4289         return infos;
   4290     }
   4291 
   4292     @Override
   4293     public long[] getProcessPss(int[] pids) {
   4294         enforceNotIsolatedCaller("getProcessPss");
   4295         long[] pss = new long[pids.length];
   4296         for (int i=pids.length-1; i>=0; i--) {
   4297             ProcessRecord proc;
   4298             int oomAdj;
   4299             synchronized (this) {
   4300                 synchronized (mPidsSelfLocked) {
   4301                     proc = mPidsSelfLocked.get(pids[i]);
   4302                     oomAdj = proc != null ? proc.setAdj : 0;
   4303                 }
   4304             }
   4305             long[] tmpUss = new long[1];
   4306             pss[i] = Debug.getPss(pids[i], tmpUss);
   4307             if (proc != null) {
   4308                 synchronized (this) {
   4309                     if (proc.thread != null && proc.setAdj == oomAdj) {
   4310                         // Record this for posterity if the process has been stable.
   4311                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   4312                     }
   4313                 }
   4314             }
   4315         }
   4316         return pss;
   4317     }
   4318 
   4319     @Override
   4320     public void killApplicationProcess(String processName, int uid) {
   4321         if (processName == null) {
   4322             return;
   4323         }
   4324 
   4325         int callerUid = Binder.getCallingUid();
   4326         // Only the system server can kill an application
   4327         if (callerUid == Process.SYSTEM_UID) {
   4328             synchronized (this) {
   4329                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   4330                 if (app != null && app.thread != null) {
   4331                     try {
   4332                         app.thread.scheduleSuicide();
   4333                     } catch (RemoteException e) {
   4334                         // If the other end already died, then our work here is done.
   4335                     }
   4336                 } else {
   4337                     Slog.w(TAG, "Process/uid not found attempting kill of "
   4338                             + processName + " / " + uid);
   4339                 }
   4340             }
   4341         } else {
   4342             throw new SecurityException(callerUid + " cannot kill app process: " +
   4343                     processName);
   4344         }
   4345     }
   4346 
   4347     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   4348         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   4349                 false, true, false, UserHandle.getUserId(uid), reason);
   4350         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   4351                 Uri.fromParts("package", packageName, null));
   4352         if (!mProcessesReady) {
   4353             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4354                     | Intent.FLAG_RECEIVER_FOREGROUND);
   4355         }
   4356         intent.putExtra(Intent.EXTRA_UID, uid);
   4357         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   4358         broadcastIntentLocked(null, null, intent,
   4359                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   4360                 false, false,
   4361                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   4362     }
   4363 
   4364     private void forceStopUserLocked(int userId, String reason) {
   4365         forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
   4366         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   4367         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4368                 | Intent.FLAG_RECEIVER_FOREGROUND);
   4369         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   4370         broadcastIntentLocked(null, null, intent,
   4371                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   4372                 false, false,
   4373                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   4374     }
   4375 
   4376     private final boolean killPackageProcessesLocked(String packageName, int appId,
   4377             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   4378             boolean doit, boolean evenPersistent, String reason) {
   4379         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   4380 
   4381         // Remove all processes this package may have touched: all with the
   4382         // same UID (except for the system or root user), and all whose name
   4383         // matches the package name.
   4384         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
   4385         final int NP = mProcessNames.getMap().size();
   4386         for (int ip=0; ip<NP; ip++) {
   4387             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   4388             final int NA = apps.size();
   4389             for (int ia=0; ia<NA; ia++) {
   4390                 ProcessRecord app = apps.valueAt(ia);
   4391                 if (app.persistent && !evenPersistent) {
   4392                     // we don't kill persistent processes
   4393                     continue;
   4394                 }
   4395                 if (app.removed) {
   4396                     if (doit) {
   4397                         procs.add(app);
   4398                     }
   4399                     continue;
   4400                 }
   4401 
   4402                 // Skip process if it doesn't meet our oom adj requirement.
   4403                 if (app.setAdj < minOomAdj) {
   4404                     continue;
   4405                 }
   4406 
   4407                 // If no package is specified, we call all processes under the
   4408                 // give user id.
   4409                 if (packageName == null) {
   4410                     if (app.userId != userId) {
   4411                         continue;
   4412                     }
   4413                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   4414                         continue;
   4415                     }
   4416                 // Package has been specified, we want to hit all processes
   4417                 // that match it.  We need to qualify this by the processes
   4418                 // that are running under the specified app and user ID.
   4419                 } else {
   4420                     if (UserHandle.getAppId(app.uid) != appId) {
   4421                         continue;
   4422                     }
   4423                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   4424                         continue;
   4425                     }
   4426                     if (!app.pkgList.containsKey(packageName)) {
   4427                         continue;
   4428                     }
   4429                 }
   4430 
   4431                 // Process has passed all conditions, kill it!
   4432                 if (!doit) {
   4433                     return true;
   4434                 }
   4435                 app.removed = true;
   4436                 procs.add(app);
   4437             }
   4438         }
   4439 
   4440         int N = procs.size();
   4441         for (int i=0; i<N; i++) {
   4442             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   4443         }
   4444         updateOomAdjLocked();
   4445         return N > 0;
   4446     }
   4447 
   4448     private final boolean forceStopPackageLocked(String name, int appId,
   4449             boolean callerWillRestart, boolean purgeCache, boolean doit,
   4450             boolean evenPersistent, int userId, String reason) {
   4451         int i;
   4452         int N;
   4453 
   4454         if (userId == UserHandle.USER_ALL && name == null) {
   4455             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   4456         }
   4457 
   4458         if (appId < 0 && name != null) {
   4459             try {
   4460                 appId = UserHandle.getAppId(
   4461                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   4462             } catch (RemoteException e) {
   4463             }
   4464         }
   4465 
   4466         if (doit) {
   4467             if (name != null) {
   4468                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
   4469                         + " user=" + userId + ": " + reason);
   4470             } else {
   4471                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   4472             }
   4473 
   4474             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   4475             for (int ip=pmap.size()-1; ip>=0; ip--) {
   4476                 SparseArray<Long> ba = pmap.valueAt(ip);
   4477                 for (i=ba.size()-1; i>=0; i--) {
   4478                     boolean remove = false;
   4479                     final int entUid = ba.keyAt(i);
   4480                     if (name != null) {
   4481                         if (userId == UserHandle.USER_ALL) {
   4482                             if (UserHandle.getAppId(entUid) == appId) {
   4483                                 remove = true;
   4484                             }
   4485                         } else {
   4486                             if (entUid == UserHandle.getUid(userId, appId)) {
   4487                                 remove = true;
   4488                             }
   4489                         }
   4490                     } else if (UserHandle.getUserId(entUid) == userId) {
   4491                         remove = true;
   4492                     }
   4493                     if (remove) {
   4494                         ba.removeAt(i);
   4495                     }
   4496                 }
   4497                 if (ba.size() == 0) {
   4498                     pmap.removeAt(ip);
   4499                 }
   4500             }
   4501         }
   4502 
   4503         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   4504                 -100, callerWillRestart, true, doit, evenPersistent,
   4505                 name == null ? ("stop user " + userId) : ("stop " + name));
   4506 
   4507         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   4508             if (!doit) {
   4509                 return true;
   4510             }
   4511             didSomething = true;
   4512         }
   4513 
   4514         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   4515             if (!doit) {
   4516                 return true;
   4517             }
   4518             didSomething = true;
   4519         }
   4520 
   4521         if (name == null) {
   4522             // Remove all sticky broadcasts from this user.
   4523             mStickyBroadcasts.remove(userId);
   4524         }
   4525 
   4526         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   4527         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   4528                 userId, providers)) {
   4529             if (!doit) {
   4530                 return true;
   4531             }
   4532             didSomething = true;
   4533         }
   4534         N = providers.size();
   4535         for (i=0; i<N; i++) {
   4536             removeDyingProviderLocked(null, providers.get(i), true);
   4537         }
   4538 
   4539         // Remove transient permissions granted from/to this package/user
   4540         removeUriPermissionsForPackageLocked(name, userId, false);
   4541 
   4542         if (name == null) {
   4543             // Remove pending intents.  For now we only do this when force
   4544             // stopping users, because we have some problems when doing this
   4545             // for packages -- app widgets are not currently cleaned up for
   4546             // such packages, so they can be left with bad pending intents.
   4547             if (mIntentSenderRecords.size() > 0) {
   4548                 Iterator<WeakReference<PendingIntentRecord>> it
   4549                         = mIntentSenderRecords.values().iterator();
   4550                 while (it.hasNext()) {
   4551                     WeakReference<PendingIntentRecord> wpir = it.next();
   4552                     if (wpir == null) {
   4553                         it.remove();
   4554                         continue;
   4555                     }
   4556                     PendingIntentRecord pir = wpir.get();
   4557                     if (pir == null) {
   4558                         it.remove();
   4559                         continue;
   4560                     }
   4561                     if (name == null) {
   4562                         // Stopping user, remove all objects for the user.
   4563                         if (pir.key.userId != userId) {
   4564                             // Not the same user, skip it.
   4565                             continue;
   4566                         }
   4567                     } else {
   4568                         if (UserHandle.getAppId(pir.uid) != appId) {
   4569                             // Different app id, skip it.
   4570                             continue;
   4571                         }
   4572                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   4573                             // Different user, skip it.
   4574                             continue;
   4575                         }
   4576                         if (!pir.key.packageName.equals(name)) {
   4577                             // Different package, skip it.
   4578                             continue;
   4579                         }
   4580                     }
   4581                     if (!doit) {
   4582                         return true;
   4583                     }
   4584                     didSomething = true;
   4585                     it.remove();
   4586                     pir.canceled = true;
   4587                     if (pir.key.activity != null) {
   4588                         pir.key.activity.pendingResults.remove(pir.ref);
   4589                     }
   4590                 }
   4591             }
   4592         }
   4593 
   4594         if (doit) {
   4595             if (purgeCache && name != null) {
   4596                 AttributeCache ac = AttributeCache.instance();
   4597                 if (ac != null) {
   4598                     ac.removePackage(name);
   4599                 }
   4600             }
   4601             if (mBooted) {
   4602                 mStackSupervisor.resumeTopActivitiesLocked();
   4603                 mStackSupervisor.scheduleIdleLocked();
   4604             }
   4605         }
   4606 
   4607         return didSomething;
   4608     }
   4609 
   4610     private final boolean removeProcessLocked(ProcessRecord app,
   4611             boolean callerWillRestart, boolean allowRestart, String reason) {
   4612         final String name = app.processName;
   4613         final int uid = app.uid;
   4614         if (DEBUG_PROCESSES) Slog.d(
   4615             TAG, "Force removing proc " + app.toShortString() + " (" + name
   4616             + "/" + uid + ")");
   4617 
   4618         mProcessNames.remove(name, uid);
   4619         mIsolatedProcesses.remove(app.uid);
   4620         if (mHeavyWeightProcess == app) {
   4621             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4622                     mHeavyWeightProcess.userId, 0));
   4623             mHeavyWeightProcess = null;
   4624         }
   4625         boolean needRestart = false;
   4626         if (app.pid > 0 && app.pid != MY_PID) {
   4627             int pid = app.pid;
   4628             synchronized (mPidsSelfLocked) {
   4629                 mPidsSelfLocked.remove(pid);
   4630                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4631             }
   4632             killUnneededProcessLocked(app, reason);
   4633             handleAppDiedLocked(app, true, allowRestart);
   4634             removeLruProcessLocked(app);
   4635 
   4636             if (app.persistent && !app.isolated) {
   4637                 if (!callerWillRestart) {
   4638                     addAppLocked(app.info, false);
   4639                 } else {
   4640                     needRestart = true;
   4641                 }
   4642             }
   4643         } else {
   4644             mRemovedProcesses.add(app);
   4645         }
   4646 
   4647         return needRestart;
   4648     }
   4649 
   4650     private final void processStartTimedOutLocked(ProcessRecord app) {
   4651         final int pid = app.pid;
   4652         boolean gone = false;
   4653         synchronized (mPidsSelfLocked) {
   4654             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   4655             if (knownApp != null && knownApp.thread == null) {
   4656                 mPidsSelfLocked.remove(pid);
   4657                 gone = true;
   4658             }
   4659         }
   4660 
   4661         if (gone) {
   4662             Slog.w(TAG, "Process " + app + " failed to attach");
   4663             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   4664                     pid, app.uid, app.processName);
   4665             mProcessNames.remove(app.processName, app.uid);
   4666             mIsolatedProcesses.remove(app.uid);
   4667             if (mHeavyWeightProcess == app) {
   4668                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4669                         mHeavyWeightProcess.userId, 0));
   4670                 mHeavyWeightProcess = null;
   4671             }
   4672             // Take care of any launching providers waiting for this process.
   4673             checkAppInLaunchingProvidersLocked(app, true);
   4674             // Take care of any services that are waiting for the process.
   4675             mServices.processStartTimedOutLocked(app);
   4676             killUnneededProcessLocked(app, "start timeout");
   4677             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   4678                 Slog.w(TAG, "Unattached app died before backup, skipping");
   4679                 try {
   4680                     IBackupManager bm = IBackupManager.Stub.asInterface(
   4681                             ServiceManager.getService(Context.BACKUP_SERVICE));
   4682                     bm.agentDisconnected(app.info.packageName);
   4683                 } catch (RemoteException e) {
   4684                     // Can't happen; the backup manager is local
   4685                 }
   4686             }
   4687             if (isPendingBroadcastProcessLocked(pid)) {
   4688                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   4689                 skipPendingBroadcastLocked(pid);
   4690             }
   4691         } else {
   4692             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   4693         }
   4694     }
   4695 
   4696     private final boolean attachApplicationLocked(IApplicationThread thread,
   4697             int pid) {
   4698 
   4699         // Find the application record that is being attached...  either via
   4700         // the pid if we are running in multiple processes, or just pull the
   4701         // next app record if we are emulating process with anonymous threads.
   4702         ProcessRecord app;
   4703         if (pid != MY_PID && pid >= 0) {
   4704             synchronized (mPidsSelfLocked) {
   4705                 app = mPidsSelfLocked.get(pid);
   4706             }
   4707         } else {
   4708             app = null;
   4709         }
   4710 
   4711         if (app == null) {
   4712             Slog.w(TAG, "No pending application record for pid " + pid
   4713                     + " (IApplicationThread " + thread + "); dropping process");
   4714             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   4715             if (pid > 0 && pid != MY_PID) {
   4716                 Process.killProcessQuiet(pid);
   4717             } else {
   4718                 try {
   4719                     thread.scheduleExit();
   4720                 } catch (Exception e) {
   4721                     // Ignore exceptions.
   4722                 }
   4723             }
   4724             return false;
   4725         }
   4726 
   4727         // If this application record is still attached to a previous
   4728         // process, clean it up now.
   4729         if (app.thread != null) {
   4730             handleAppDiedLocked(app, true, true);
   4731         }
   4732 
   4733         // Tell the process all about itself.
   4734 
   4735         if (localLOGV) Slog.v(
   4736                 TAG, "Binding process pid " + pid + " to record " + app);
   4737 
   4738         final String processName = app.processName;
   4739         try {
   4740             AppDeathRecipient adr = new AppDeathRecipient(
   4741                     app, pid, thread);
   4742             thread.asBinder().linkToDeath(adr, 0);
   4743             app.deathRecipient = adr;
   4744         } catch (RemoteException e) {
   4745             app.resetPackageList(mProcessStats);
   4746             startProcessLocked(app, "link fail", processName);
   4747             return false;
   4748         }
   4749 
   4750         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   4751 
   4752         app.makeActive(thread, mProcessStats);
   4753         app.curAdj = app.setAdj = -100;
   4754         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
   4755         app.forcingToForeground = null;
   4756         app.foregroundServices = false;
   4757         app.hasShownUi = false;
   4758         app.debugging = false;
   4759         app.cached = false;
   4760 
   4761         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4762 
   4763         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   4764         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   4765 
   4766         if (!normalMode) {
   4767             Slog.i(TAG, "Launching preboot mode app: " + app);
   4768         }
   4769 
   4770         if (localLOGV) Slog.v(
   4771             TAG, "New app record " + app
   4772             + " thread=" + thread.asBinder() + " pid=" + pid);
   4773         try {
   4774             int testMode = IApplicationThread.DEBUG_OFF;
   4775             if (mDebugApp != null && mDebugApp.equals(processName)) {
   4776                 testMode = mWaitForDebugger
   4777                     ? IApplicationThread.DEBUG_WAIT
   4778                     : IApplicationThread.DEBUG_ON;
   4779                 app.debugging = true;
   4780                 if (mDebugTransient) {
   4781                     mDebugApp = mOrigDebugApp;
   4782                     mWaitForDebugger = mOrigWaitForDebugger;
   4783                 }
   4784             }
   4785             String profileFile = app.instrumentationProfileFile;
   4786             ParcelFileDescriptor profileFd = null;
   4787             boolean profileAutoStop = false;
   4788             if (mProfileApp != null && mProfileApp.equals(processName)) {
   4789                 mProfileProc = app;
   4790                 profileFile = mProfileFile;
   4791                 profileFd = mProfileFd;
   4792                 profileAutoStop = mAutoStopProfiler;
   4793             }
   4794             boolean enableOpenGlTrace = false;
   4795             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   4796                 enableOpenGlTrace = true;
   4797                 mOpenGlTraceApp = null;
   4798             }
   4799 
   4800             // If the app is being launched for restore or full backup, set it up specially
   4801             boolean isRestrictedBackupMode = false;
   4802             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   4803                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   4804                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   4805                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   4806             }
   4807 
   4808             ensurePackageDexOpt(app.instrumentationInfo != null
   4809                     ? app.instrumentationInfo.packageName
   4810                     : app.info.packageName);
   4811             if (app.instrumentationClass != null) {
   4812                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   4813             }
   4814             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   4815                     + processName + " with config " + mConfiguration);
   4816             ApplicationInfo appInfo = app.instrumentationInfo != null
   4817                     ? app.instrumentationInfo : app.info;
   4818             app.compat = compatibilityInfoForPackageLocked(appInfo);
   4819             if (profileFd != null) {
   4820                 profileFd = profileFd.dup();
   4821             }
   4822             thread.bindApplication(processName, appInfo, providers,
   4823                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   4824                     app.instrumentationArguments, app.instrumentationWatcher,
   4825                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   4826                     isRestrictedBackupMode || !normalMode, app.persistent,
   4827                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   4828                     mCoreSettingsObserver.getCoreSettingsLocked());
   4829             updateLruProcessLocked(app, false, false);
   4830             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   4831         } catch (Exception e) {
   4832             // todo: Yikes!  What should we do?  For now we will try to
   4833             // start another process, but that could easily get us in
   4834             // an infinite loop of restarting processes...
   4835             Slog.w(TAG, "Exception thrown during bind!", e);
   4836 
   4837             app.resetPackageList(mProcessStats);
   4838             app.unlinkDeathRecipient();
   4839             startProcessLocked(app, "bind fail", processName);
   4840             return false;
   4841         }
   4842 
   4843         // Remove this record from the list of starting applications.
   4844         mPersistentStartingProcesses.remove(app);
   4845         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   4846                 "Attach application locked removing on hold: " + app);
   4847         mProcessesOnHold.remove(app);
   4848 
   4849         boolean badApp = false;
   4850         boolean didSomething = false;
   4851 
   4852         // See if the top visible activity is waiting to run in this process...
   4853         if (normalMode) {
   4854             try {
   4855                 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
   4856                     didSomething = true;
   4857                 }
   4858             } catch (Exception e) {
   4859                 badApp = true;
   4860             }
   4861         }
   4862 
   4863         // Find any services that should be running in this process...
   4864         if (!badApp) {
   4865             try {
   4866                 didSomething |= mServices.attachApplicationLocked(app, processName);
   4867             } catch (Exception e) {
   4868                 badApp = true;
   4869             }
   4870         }
   4871 
   4872         // Check if a next-broadcast receiver is in this process...
   4873         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   4874             try {
   4875                 didSomething |= sendPendingBroadcastsLocked(app);
   4876             } catch (Exception e) {
   4877                 // If the app died trying to launch the receiver we declare it 'bad'
   4878                 badApp = true;
   4879             }
   4880         }
   4881 
   4882         // Check whether the next backup agent is in this process...
   4883         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   4884             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   4885             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   4886             try {
   4887                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   4888                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   4889                         mBackupTarget.backupMode);
   4890             } catch (Exception e) {
   4891                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   4892                 e.printStackTrace();
   4893             }
   4894         }
   4895 
   4896         if (badApp) {
   4897             // todo: Also need to kill application to deal with all
   4898             // kinds of exceptions.
   4899             handleAppDiedLocked(app, false, true);
   4900             return false;
   4901         }
   4902 
   4903         if (!didSomething) {
   4904             updateOomAdjLocked();
   4905         }
   4906 
   4907         return true;
   4908     }
   4909 
   4910     @Override
   4911     public final void attachApplication(IApplicationThread thread) {
   4912         synchronized (this) {
   4913             int callingPid = Binder.getCallingPid();
   4914             final long origId = Binder.clearCallingIdentity();
   4915             attachApplicationLocked(thread, callingPid);
   4916             Binder.restoreCallingIdentity(origId);
   4917         }
   4918     }
   4919 
   4920     @Override
   4921     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   4922         final long origId = Binder.clearCallingIdentity();
   4923         synchronized (this) {
   4924             ActivityStack stack = ActivityRecord.getStackLocked(token);
   4925             if (stack != null) {
   4926                 ActivityRecord r =
   4927                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   4928                 if (stopProfiling) {
   4929                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   4930                         try {
   4931                             mProfileFd.close();
   4932                         } catch (IOException e) {
   4933                         }
   4934                         clearProfilerLocked();
   4935                     }
   4936                 }
   4937             }
   4938         }
   4939         Binder.restoreCallingIdentity(origId);
   4940     }
   4941 
   4942     void enableScreenAfterBoot() {
   4943         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   4944                 SystemClock.uptimeMillis());
   4945         mWindowManager.enableScreenAfterBoot();
   4946 
   4947         synchronized (this) {
   4948             updateEventDispatchingLocked();
   4949         }
   4950     }
   4951 
   4952     @Override
   4953     public void showBootMessage(final CharSequence msg, final boolean always) {
   4954         enforceNotIsolatedCaller("showBootMessage");
   4955         mWindowManager.showBootMessage(msg, always);
   4956     }
   4957 
   4958     @Override
   4959     public void dismissKeyguardOnNextActivity() {
   4960         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
   4961         final long token = Binder.clearCallingIdentity();
   4962         try {
   4963             synchronized (this) {
   4964                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   4965                 if (mLockScreenShown) {
   4966                     mLockScreenShown = false;
   4967                     comeOutOfSleepIfNeededLocked();
   4968                 }
   4969                 mStackSupervisor.setDismissKeyguard(true);
   4970             }
   4971         } finally {
   4972             Binder.restoreCallingIdentity(token);
   4973         }
   4974     }
   4975 
   4976     final void finishBooting() {
   4977         IntentFilter pkgFilter = new IntentFilter();
   4978         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   4979         pkgFilter.addDataScheme("package");
   4980         mContext.registerReceiver(new BroadcastReceiver() {
   4981             @Override
   4982             public void onReceive(Context context, Intent intent) {
   4983                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   4984                 if (pkgs != null) {
   4985                     for (String pkg : pkgs) {
   4986                         synchronized (ActivityManagerService.this) {
   4987                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
   4988                                     "finished booting")) {
   4989                                 setResultCode(Activity.RESULT_OK);
   4990                                 return;
   4991                             }
   4992                         }
   4993                     }
   4994                 }
   4995             }
   4996         }, pkgFilter);
   4997 
   4998         synchronized (this) {
   4999             // Ensure that any processes we had put on hold are now started
   5000             // up.
   5001             final int NP = mProcessesOnHold.size();
   5002             if (NP > 0) {
   5003                 ArrayList<ProcessRecord> procs =
   5004                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   5005                 for (int ip=0; ip<NP; ip++) {
   5006                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   5007                             + procs.get(ip));
   5008                     startProcessLocked(procs.get(ip), "on-hold", null);
   5009                 }
   5010             }
   5011 
   5012             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   5013                 // Start looking for apps that are abusing wake locks.
   5014                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   5015                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   5016                 // Tell anyone interested that we are done booting!
   5017                 SystemProperties.set("sys.boot_completed", "1");
   5018                 SystemProperties.set("dev.bootcomplete", "1");
   5019                 for (int i=0; i<mStartedUsers.size(); i++) {
   5020                     UserStartedState uss = mStartedUsers.valueAt(i);
   5021                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   5022                         uss.mState = UserStartedState.STATE_RUNNING;
   5023                         final int userId = mStartedUsers.keyAt(i);
   5024                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   5025                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   5026                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   5027                         broadcastIntentLocked(null, null, intent, null,
   5028                                 new IIntentReceiver.Stub() {
   5029                                     @Override
   5030                                     public void performReceive(Intent intent, int resultCode,
   5031                                             String data, Bundle extras, boolean ordered,
   5032                                             boolean sticky, int sendingUser) {
   5033                                         synchronized (ActivityManagerService.this) {
   5034                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   5035                                                     true, false);
   5036                                         }
   5037                                     }
   5038                                 },
   5039                                 0, null, null,
   5040                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   5041                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
   5042                                 userId);
   5043                     }
   5044                 }
   5045             }
   5046         }
   5047     }
   5048 
   5049     final void ensureBootCompleted() {
   5050         boolean booting;
   5051         boolean enableScreen;
   5052         synchronized (this) {
   5053             booting = mBooting;
   5054             mBooting = false;
   5055             enableScreen = !mBooted;
   5056             mBooted = true;
   5057         }
   5058 
   5059         if (booting) {
   5060             finishBooting();
   5061         }
   5062 
   5063         if (enableScreen) {
   5064             enableScreenAfterBoot();
   5065         }
   5066     }
   5067 
   5068     @Override
   5069     public final void activityResumed(IBinder token) {
   5070         final long origId = Binder.clearCallingIdentity();
   5071         synchronized(this) {
   5072             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5073             if (stack != null) {
   5074                 ActivityRecord.activityResumedLocked(token);
   5075             }
   5076         }
   5077         Binder.restoreCallingIdentity(origId);
   5078     }
   5079 
   5080     @Override
   5081     public final void activityPaused(IBinder token) {
   5082         final long origId = Binder.clearCallingIdentity();
   5083         synchronized(this) {
   5084             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5085             if (stack != null) {
   5086                 stack.activityPausedLocked(token, false);
   5087             }
   5088         }
   5089         Binder.restoreCallingIdentity(origId);
   5090     }
   5091 
   5092     @Override
   5093     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   5094             CharSequence description) {
   5095         if (localLOGV) Slog.v(
   5096             TAG, "Activity stopped: token=" + token);
   5097 
   5098         // Refuse possible leaked file descriptors
   5099         if (icicle != null && icicle.hasFileDescriptors()) {
   5100             throw new IllegalArgumentException("File descriptors passed in Bundle");
   5101         }
   5102 
   5103         ActivityRecord r = null;
   5104 
   5105         final long origId = Binder.clearCallingIdentity();
   5106 
   5107         synchronized (this) {
   5108             r = ActivityRecord.isInStackLocked(token);
   5109             if (r != null) {
   5110                 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   5111             }
   5112         }
   5113 
   5114         if (r != null) {
   5115             sendPendingThumbnail(r, null, null, null, false);
   5116         }
   5117 
   5118         trimApplications();
   5119 
   5120         Binder.restoreCallingIdentity(origId);
   5121     }
   5122 
   5123     @Override
   5124     public final void activityDestroyed(IBinder token) {
   5125         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   5126         synchronized (this) {
   5127             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5128             if (stack != null) {
   5129                 stack.activityDestroyedLocked(token);
   5130             }
   5131         }
   5132     }
   5133 
   5134     @Override
   5135     public String getCallingPackage(IBinder token) {
   5136         synchronized (this) {
   5137             ActivityRecord r = getCallingRecordLocked(token);
   5138             return r != null ? r.info.packageName : null;
   5139         }
   5140     }
   5141 
   5142     @Override
   5143     public ComponentName getCallingActivity(IBinder token) {
   5144         synchronized (this) {
   5145             ActivityRecord r = getCallingRecordLocked(token);
   5146             return r != null ? r.intent.getComponent() : null;
   5147         }
   5148     }
   5149 
   5150     private ActivityRecord getCallingRecordLocked(IBinder token) {
   5151         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5152         if (r == null) {
   5153             return null;
   5154         }
   5155         return r.resultTo;
   5156     }
   5157 
   5158     @Override
   5159     public ComponentName getActivityClassForToken(IBinder token) {
   5160         synchronized(this) {
   5161             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5162             if (r == null) {
   5163                 return null;
   5164             }
   5165             return r.intent.getComponent();
   5166         }
   5167     }
   5168 
   5169     @Override
   5170     public String getPackageForToken(IBinder token) {
   5171         synchronized(this) {
   5172             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5173             if (r == null) {
   5174                 return null;
   5175             }
   5176             return r.packageName;
   5177         }
   5178     }
   5179 
   5180     @Override
   5181     public IIntentSender getIntentSender(int type,
   5182             String packageName, IBinder token, String resultWho,
   5183             int requestCode, Intent[] intents, String[] resolvedTypes,
   5184             int flags, Bundle options, int userId) {
   5185         enforceNotIsolatedCaller("getIntentSender");
   5186         // Refuse possible leaked file descriptors
   5187         if (intents != null) {
   5188             if (intents.length < 1) {
   5189                 throw new IllegalArgumentException("Intents array length must be >= 1");
   5190             }
   5191             for (int i=0; i<intents.length; i++) {
   5192                 Intent intent = intents[i];
   5193                 if (intent != null) {
   5194                     if (intent.hasFileDescriptors()) {
   5195                         throw new IllegalArgumentException("File descriptors passed in Intent");
   5196                     }
   5197                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   5198                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   5199                         throw new IllegalArgumentException(
   5200                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   5201                     }
   5202                     intents[i] = new Intent(intent);
   5203                 }
   5204             }
   5205             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   5206                 throw new IllegalArgumentException(
   5207                         "Intent array length does not match resolvedTypes length");
   5208             }
   5209         }
   5210         if (options != null) {
   5211             if (options.hasFileDescriptors()) {
   5212                 throw new IllegalArgumentException("File descriptors passed in options");
   5213             }
   5214         }
   5215 
   5216         synchronized(this) {
   5217             int callingUid = Binder.getCallingUid();
   5218             int origUserId = userId;
   5219             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   5220                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
   5221                     "getIntentSender", null);
   5222             if (origUserId == UserHandle.USER_CURRENT) {
   5223                 // We don't want to evaluate this until the pending intent is
   5224                 // actually executed.  However, we do want to always do the
   5225                 // security checking for it above.
   5226                 userId = UserHandle.USER_CURRENT;
   5227             }
   5228             try {
   5229                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   5230                     int uid = AppGlobals.getPackageManager()
   5231                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   5232                     if (!UserHandle.isSameApp(callingUid, uid)) {
   5233                         String msg = "Permission Denial: getIntentSender() from pid="
   5234                             + Binder.getCallingPid()
   5235                             + ", uid=" + Binder.getCallingUid()
   5236                             + ", (need uid=" + uid + ")"
   5237                             + " is not allowed to send as package " + packageName;
   5238                         Slog.w(TAG, msg);
   5239                         throw new SecurityException(msg);
   5240                     }
   5241                 }
   5242 
   5243                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   5244                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   5245 
   5246             } catch (RemoteException e) {
   5247                 throw new SecurityException(e);
   5248             }
   5249         }
   5250     }
   5251 
   5252     IIntentSender getIntentSenderLocked(int type, String packageName,
   5253             int callingUid, int userId, IBinder token, String resultWho,
   5254             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   5255             Bundle options) {
   5256         if (DEBUG_MU)
   5257             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   5258         ActivityRecord activity = null;
   5259         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   5260             activity = ActivityRecord.isInStackLocked(token);
   5261             if (activity == null) {
   5262                 return null;
   5263             }
   5264             if (activity.finishing) {
   5265                 return null;
   5266             }
   5267         }
   5268 
   5269         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   5270         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   5271         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   5272         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   5273                 |PendingIntent.FLAG_UPDATE_CURRENT);
   5274 
   5275         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   5276                 type, packageName, activity, resultWho,
   5277                 requestCode, intents, resolvedTypes, flags, options, userId);
   5278         WeakReference<PendingIntentRecord> ref;
   5279         ref = mIntentSenderRecords.get(key);
   5280         PendingIntentRecord rec = ref != null ? ref.get() : null;
   5281         if (rec != null) {
   5282             if (!cancelCurrent) {
   5283                 if (updateCurrent) {
   5284                     if (rec.key.requestIntent != null) {
   5285                         rec.key.requestIntent.replaceExtras(intents != null ?
   5286                                 intents[intents.length - 1] : null);
   5287                     }
   5288                     if (intents != null) {
   5289                         intents[intents.length-1] = rec.key.requestIntent;
   5290                         rec.key.allIntents = intents;
   5291                         rec.key.allResolvedTypes = resolvedTypes;
   5292                     } else {
   5293                         rec.key.allIntents = null;
   5294                         rec.key.allResolvedTypes = null;
   5295                     }
   5296                 }
   5297                 return rec;
   5298             }
   5299             rec.canceled = true;
   5300             mIntentSenderRecords.remove(key);
   5301         }
   5302         if (noCreate) {
   5303             return rec;
   5304         }
   5305         rec = new PendingIntentRecord(this, key, callingUid);
   5306         mIntentSenderRecords.put(key, rec.ref);
   5307         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   5308             if (activity.pendingResults == null) {
   5309                 activity.pendingResults
   5310                         = new HashSet<WeakReference<PendingIntentRecord>>();
   5311             }
   5312             activity.pendingResults.add(rec.ref);
   5313         }
   5314         return rec;
   5315     }
   5316 
   5317     @Override
   5318     public void cancelIntentSender(IIntentSender sender) {
   5319         if (!(sender instanceof PendingIntentRecord)) {
   5320             return;
   5321         }
   5322         synchronized(this) {
   5323             PendingIntentRecord rec = (PendingIntentRecord)sender;
   5324             try {
   5325                 int uid = AppGlobals.getPackageManager()
   5326                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   5327                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   5328                     String msg = "Permission Denial: cancelIntentSender() from pid="
   5329                         + Binder.getCallingPid()
   5330                         + ", uid=" + Binder.getCallingUid()
   5331                         + " is not allowed to cancel packges "
   5332                         + rec.key.packageName;
   5333                     Slog.w(TAG, msg);
   5334                     throw new SecurityException(msg);
   5335                 }
   5336             } catch (RemoteException e) {
   5337                 throw new SecurityException(e);
   5338             }
   5339             cancelIntentSenderLocked(rec, true);
   5340         }
   5341     }
   5342 
   5343     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   5344         rec.canceled = true;
   5345         mIntentSenderRecords.remove(rec.key);
   5346         if (cleanActivity && rec.key.activity != null) {
   5347             rec.key.activity.pendingResults.remove(rec.ref);
   5348         }
   5349     }
   5350 
   5351     @Override
   5352     public String getPackageForIntentSender(IIntentSender pendingResult) {
   5353         if (!(pendingResult instanceof PendingIntentRecord)) {
   5354             return null;
   5355         }
   5356         try {
   5357             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5358             return res.key.packageName;
   5359         } catch (ClassCastException e) {
   5360         }
   5361         return null;
   5362     }
   5363 
   5364     @Override
   5365     public int getUidForIntentSender(IIntentSender sender) {
   5366         if (sender instanceof PendingIntentRecord) {
   5367             try {
   5368                 PendingIntentRecord res = (PendingIntentRecord)sender;
   5369                 return res.uid;
   5370             } catch (ClassCastException e) {
   5371             }
   5372         }
   5373         return -1;
   5374     }
   5375 
   5376     @Override
   5377     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   5378         if (!(pendingResult instanceof PendingIntentRecord)) {
   5379             return false;
   5380         }
   5381         try {
   5382             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5383             if (res.key.allIntents == null) {
   5384                 return false;
   5385             }
   5386             for (int i=0; i<res.key.allIntents.length; i++) {
   5387                 Intent intent = res.key.allIntents[i];
   5388                 if (intent.getPackage() != null && intent.getComponent() != null) {
   5389                     return false;
   5390                 }
   5391             }
   5392             return true;
   5393         } catch (ClassCastException e) {
   5394         }
   5395         return false;
   5396     }
   5397 
   5398     @Override
   5399     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   5400         if (!(pendingResult instanceof PendingIntentRecord)) {
   5401             return false;
   5402         }
   5403         try {
   5404             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5405             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   5406                 return true;
   5407             }
   5408             return false;
   5409         } catch (ClassCastException e) {
   5410         }
   5411         return false;
   5412     }
   5413 
   5414     @Override
   5415     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   5416         if (!(pendingResult instanceof PendingIntentRecord)) {
   5417             return null;
   5418         }
   5419         try {
   5420             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5421             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   5422         } catch (ClassCastException e) {
   5423         }
   5424         return null;
   5425     }
   5426 
   5427     @Override
   5428     public void setProcessLimit(int max) {
   5429         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   5430                 "setProcessLimit()");
   5431         synchronized (this) {
   5432             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   5433             mProcessLimitOverride = max;
   5434         }
   5435         trimApplications();
   5436     }
   5437 
   5438     @Override
   5439     public int getProcessLimit() {
   5440         synchronized (this) {
   5441             return mProcessLimitOverride;
   5442         }
   5443     }
   5444 
   5445     void foregroundTokenDied(ForegroundToken token) {
   5446         synchronized (ActivityManagerService.this) {
   5447             synchronized (mPidsSelfLocked) {
   5448                 ForegroundToken cur
   5449                     = mForegroundProcesses.get(token.pid);
   5450                 if (cur != token) {
   5451                     return;
   5452                 }
   5453                 mForegroundProcesses.remove(token.pid);
   5454                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   5455                 if (pr == null) {
   5456                     return;
   5457                 }
   5458                 pr.forcingToForeground = null;
   5459                 pr.foregroundServices = false;
   5460             }
   5461             updateOomAdjLocked();
   5462         }
   5463     }
   5464 
   5465     @Override
   5466     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   5467         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   5468                 "setProcessForeground()");
   5469         synchronized(this) {
   5470             boolean changed = false;
   5471 
   5472             synchronized (mPidsSelfLocked) {
   5473                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   5474                 if (pr == null && isForeground) {
   5475                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   5476                     return;
   5477                 }
   5478                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   5479                 if (oldToken != null) {
   5480                     oldToken.token.unlinkToDeath(oldToken, 0);
   5481                     mForegroundProcesses.remove(pid);
   5482                     if (pr != null) {
   5483                         pr.forcingToForeground = null;
   5484                     }
   5485                     changed = true;
   5486                 }
   5487                 if (isForeground && token != null) {
   5488                     ForegroundToken newToken = new ForegroundToken() {
   5489                         @Override
   5490                         public void binderDied() {
   5491                             foregroundTokenDied(this);
   5492                         }
   5493                     };
   5494                     newToken.pid = pid;
   5495                     newToken.token = token;
   5496                     try {
   5497                         token.linkToDeath(newToken, 0);
   5498                         mForegroundProcesses.put(pid, newToken);
   5499                         pr.forcingToForeground = token;
   5500                         changed = true;
   5501                     } catch (RemoteException e) {
   5502                         // If the process died while doing this, we will later
   5503                         // do the cleanup with the process death link.
   5504                     }
   5505                 }
   5506             }
   5507 
   5508             if (changed) {
   5509                 updateOomAdjLocked();
   5510             }
   5511         }
   5512     }
   5513 
   5514     // =========================================================
   5515     // PERMISSIONS
   5516     // =========================================================
   5517 
   5518     static class PermissionController extends IPermissionController.Stub {
   5519         ActivityManagerService mActivityManagerService;
   5520         PermissionController(ActivityManagerService activityManagerService) {
   5521             mActivityManagerService = activityManagerService;
   5522         }
   5523 
   5524         @Override
   5525         public boolean checkPermission(String permission, int pid, int uid) {
   5526             return mActivityManagerService.checkPermission(permission, pid,
   5527                     uid) == PackageManager.PERMISSION_GRANTED;
   5528         }
   5529     }
   5530 
   5531     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   5532         @Override
   5533         public int checkComponentPermission(String permission, int pid, int uid,
   5534                 int owningUid, boolean exported) {
   5535             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   5536                     owningUid, exported);
   5537         }
   5538 
   5539         @Override
   5540         public Object getAMSLock() {
   5541             return ActivityManagerService.this;
   5542         }
   5543     }
   5544 
   5545     /**
   5546      * This can be called with or without the global lock held.
   5547      */
   5548     int checkComponentPermission(String permission, int pid, int uid,
   5549             int owningUid, boolean exported) {
   5550         // We might be performing an operation on behalf of an indirect binder
   5551         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   5552         // client identity accordingly before proceeding.
   5553         Identity tlsIdentity = sCallerIdentity.get();
   5554         if (tlsIdentity != null) {
   5555             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   5556                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   5557             uid = tlsIdentity.uid;
   5558             pid = tlsIdentity.pid;
   5559         }
   5560 
   5561         if (pid == MY_PID) {
   5562             return PackageManager.PERMISSION_GRANTED;
   5563         }
   5564 
   5565         return ActivityManager.checkComponentPermission(permission, uid,
   5566                 owningUid, exported);
   5567     }
   5568 
   5569     /**
   5570      * As the only public entry point for permissions checking, this method
   5571      * can enforce the semantic that requesting a check on a null global
   5572      * permission is automatically denied.  (Internally a null permission
   5573      * string is used when calling {@link #checkComponentPermission} in cases
   5574      * when only uid-based security is needed.)
   5575      *
   5576      * This can be called with or without the global lock held.
   5577      */
   5578     @Override
   5579     public int checkPermission(String permission, int pid, int uid) {
   5580         if (permission == null) {
   5581             return PackageManager.PERMISSION_DENIED;
   5582         }
   5583         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   5584     }
   5585 
   5586     /**
   5587      * Binder IPC calls go through the public entry point.
   5588      * This can be called with or without the global lock held.
   5589      */
   5590     int checkCallingPermission(String permission) {
   5591         return checkPermission(permission,
   5592                 Binder.getCallingPid(),
   5593                 UserHandle.getAppId(Binder.getCallingUid()));
   5594     }
   5595 
   5596     /**
   5597      * This can be called with or without the global lock held.
   5598      */
   5599     void enforceCallingPermission(String permission, String func) {
   5600         if (checkCallingPermission(permission)
   5601                 == PackageManager.PERMISSION_GRANTED) {
   5602             return;
   5603         }
   5604 
   5605         String msg = "Permission Denial: " + func + " from pid="
   5606                 + Binder.getCallingPid()
   5607                 + ", uid=" + Binder.getCallingUid()
   5608                 + " requires " + permission;
   5609         Slog.w(TAG, msg);
   5610         throw new SecurityException(msg);
   5611     }
   5612 
   5613     /**
   5614      * Determine if UID is holding permissions required to access {@link Uri} in
   5615      * the given {@link ProviderInfo}. Final permission checking is always done
   5616      * in {@link ContentProvider}.
   5617      */
   5618     private final boolean checkHoldingPermissionsLocked(
   5619             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   5620         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5621                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   5622 
   5623         if (pi.applicationInfo.uid == uid) {
   5624             return true;
   5625         } else if (!pi.exported) {
   5626             return false;
   5627         }
   5628 
   5629         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   5630         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   5631         try {
   5632             // check if target holds top-level <provider> permissions
   5633             if (!readMet && pi.readPermission != null
   5634                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   5635                 readMet = true;
   5636             }
   5637             if (!writeMet && pi.writePermission != null
   5638                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   5639                 writeMet = true;
   5640             }
   5641 
   5642             // track if unprotected read/write is allowed; any denied
   5643             // <path-permission> below removes this ability
   5644             boolean allowDefaultRead = pi.readPermission == null;
   5645             boolean allowDefaultWrite = pi.writePermission == null;
   5646 
   5647             // check if target holds any <path-permission> that match uri
   5648             final PathPermission[] pps = pi.pathPermissions;
   5649             if (pps != null) {
   5650                 final String path = uri.getPath();
   5651                 int i = pps.length;
   5652                 while (i > 0 && (!readMet || !writeMet)) {
   5653                     i--;
   5654                     PathPermission pp = pps[i];
   5655                     if (pp.match(path)) {
   5656                         if (!readMet) {
   5657                             final String pprperm = pp.getReadPermission();
   5658                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   5659                                     + pprperm + " for " + pp.getPath()
   5660                                     + ": match=" + pp.match(path)
   5661                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   5662                             if (pprperm != null) {
   5663                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
   5664                                     readMet = true;
   5665                                 } else {
   5666                                     allowDefaultRead = false;
   5667                                 }
   5668                             }
   5669                         }
   5670                         if (!writeMet) {
   5671                             final String ppwperm = pp.getWritePermission();
   5672                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   5673                                     + ppwperm + " for " + pp.getPath()
   5674                                     + ": match=" + pp.match(path)
   5675                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   5676                             if (ppwperm != null) {
   5677                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
   5678                                     writeMet = true;
   5679                                 } else {
   5680                                     allowDefaultWrite = false;
   5681                                 }
   5682                             }
   5683                         }
   5684                     }
   5685                 }
   5686             }
   5687 
   5688             // grant unprotected <provider> read/write, if not blocked by
   5689             // <path-permission> above
   5690             if (allowDefaultRead) readMet = true;
   5691             if (allowDefaultWrite) writeMet = true;
   5692 
   5693         } catch (RemoteException e) {
   5694             return false;
   5695         }
   5696 
   5697         return readMet && writeMet;
   5698     }
   5699 
   5700     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
   5701         ProviderInfo pi = null;
   5702         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   5703         if (cpr != null) {
   5704             pi = cpr.info;
   5705         } else {
   5706             try {
   5707                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   5708                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
   5709             } catch (RemoteException ex) {
   5710             }
   5711         }
   5712         return pi;
   5713     }
   5714 
   5715     private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
   5716         ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   5717         if (targetUris != null) {
   5718             return targetUris.get(uri);
   5719         } else {
   5720             return null;
   5721         }
   5722     }
   5723 
   5724     private UriPermission findOrCreateUriPermissionLocked(
   5725             String sourcePkg, String targetPkg, int targetUid, Uri uri) {
   5726         ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   5727         if (targetUris == null) {
   5728             targetUris = Maps.newArrayMap();
   5729             mGrantedUriPermissions.put(targetUid, targetUris);
   5730         }
   5731 
   5732         UriPermission perm = targetUris.get(uri);
   5733         if (perm == null) {
   5734             perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
   5735             targetUris.put(uri, perm);
   5736         }
   5737 
   5738         return perm;
   5739     }
   5740 
   5741     private final boolean checkUriPermissionLocked(
   5742             Uri uri, int uid, int modeFlags, int minStrength) {
   5743         // Root gets to do everything.
   5744         if (uid == 0) {
   5745             return true;
   5746         }
   5747         ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   5748         if (perms == null) return false;
   5749         UriPermission perm = perms.get(uri);
   5750         if (perm == null) return false;
   5751         return perm.getStrength(modeFlags) >= minStrength;
   5752     }
   5753 
   5754     @Override
   5755     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   5756         enforceNotIsolatedCaller("checkUriPermission");
   5757 
   5758         // Another redirected-binder-call permissions check as in
   5759         // {@link checkComponentPermission}.
   5760         Identity tlsIdentity = sCallerIdentity.get();
   5761         if (tlsIdentity != null) {
   5762             uid = tlsIdentity.uid;
   5763             pid = tlsIdentity.pid;
   5764         }
   5765 
   5766         // Our own process gets to do everything.
   5767         if (pid == MY_PID) {
   5768             return PackageManager.PERMISSION_GRANTED;
   5769         }
   5770         synchronized(this) {
   5771             return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
   5772                     ? PackageManager.PERMISSION_GRANTED
   5773                     : PackageManager.PERMISSION_DENIED;
   5774         }
   5775     }
   5776 
   5777     /**
   5778      * Check if the targetPkg can be granted permission to access uri by
   5779      * the callingUid using the given modeFlags.  Throws a security exception
   5780      * if callingUid is not allowed to do this.  Returns the uid of the target
   5781      * if the URI permission grant should be performed; returns -1 if it is not
   5782      * needed (for example targetPkg already has permission to access the URI).
   5783      * If you already know the uid of the target, you can supply it in
   5784      * lastTargetUid else set that to -1.
   5785      */
   5786     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   5787             Uri uri, int modeFlags, int lastTargetUid) {
   5788         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   5789         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5790                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5791         if (modeFlags == 0) {
   5792             return -1;
   5793         }
   5794 
   5795         if (targetPkg != null) {
   5796             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5797                     "Checking grant " + targetPkg + " permission to " + uri);
   5798         }
   5799 
   5800         final IPackageManager pm = AppGlobals.getPackageManager();
   5801 
   5802         // If this is not a content: uri, we can't do anything with it.
   5803         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   5804             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5805                     "Can't grant URI permission for non-content URI: " + uri);
   5806             return -1;
   5807         }
   5808 
   5809         final String authority = uri.getAuthority();
   5810         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
   5811         if (pi == null) {
   5812             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   5813             return -1;
   5814         }
   5815 
   5816         int targetUid = lastTargetUid;
   5817         if (targetUid < 0 && targetPkg != null) {
   5818             try {
   5819                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   5820                 if (targetUid < 0) {
   5821                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5822                             "Can't grant URI permission no uid for: " + targetPkg);
   5823                     return -1;
   5824                 }
   5825             } catch (RemoteException ex) {
   5826                 return -1;
   5827             }
   5828         }
   5829 
   5830         if (targetUid >= 0) {
   5831             // First...  does the target actually need this permission?
   5832             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   5833                 // No need to grant the target this permission.
   5834                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5835                         "Target " + targetPkg + " already has full permission to " + uri);
   5836                 return -1;
   5837             }
   5838         } else {
   5839             // First...  there is no target package, so can anyone access it?
   5840             boolean allowed = pi.exported;
   5841             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5842                 if (pi.readPermission != null) {
   5843                     allowed = false;
   5844                 }
   5845             }
   5846             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5847                 if (pi.writePermission != null) {
   5848                     allowed = false;
   5849                 }
   5850             }
   5851             if (allowed) {
   5852                 return -1;
   5853             }
   5854         }
   5855 
   5856         // Second...  is the provider allowing granting of URI permissions?
   5857         if (!pi.grantUriPermissions) {
   5858             throw new SecurityException("Provider " + pi.packageName
   5859                     + "/" + pi.name
   5860                     + " does not allow granting of Uri permissions (uri "
   5861                     + uri + ")");
   5862         }
   5863         if (pi.uriPermissionPatterns != null) {
   5864             final int N = pi.uriPermissionPatterns.length;
   5865             boolean allowed = false;
   5866             for (int i=0; i<N; i++) {
   5867                 if (pi.uriPermissionPatterns[i] != null
   5868                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   5869                     allowed = true;
   5870                     break;
   5871                 }
   5872             }
   5873             if (!allowed) {
   5874                 throw new SecurityException("Provider " + pi.packageName
   5875                         + "/" + pi.name
   5876                         + " does not allow granting of permission to path of Uri "
   5877                         + uri);
   5878             }
   5879         }
   5880 
   5881         // Third...  does the caller itself have permission to access
   5882         // this uri?
   5883         if (callingUid != Process.myUid()) {
   5884             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   5885                 // Require they hold a strong enough Uri permission
   5886                 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   5887                         : UriPermission.STRENGTH_OWNED;
   5888                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
   5889                     throw new SecurityException("Uid " + callingUid
   5890                             + " does not have permission to uri " + uri);
   5891                 }
   5892             }
   5893         }
   5894 
   5895         return targetUid;
   5896     }
   5897 
   5898     @Override
   5899     public int checkGrantUriPermission(int callingUid, String targetPkg,
   5900             Uri uri, int modeFlags) {
   5901         enforceNotIsolatedCaller("checkGrantUriPermission");
   5902         synchronized(this) {
   5903             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5904         }
   5905     }
   5906 
   5907     void grantUriPermissionUncheckedLocked(
   5908             int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   5909         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   5910         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5911                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5912         if (modeFlags == 0) {
   5913             return;
   5914         }
   5915 
   5916         // So here we are: the caller has the assumed permission
   5917         // to the uri, and the target doesn't.  Let's now give this to
   5918         // the target.
   5919 
   5920         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5921                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   5922 
   5923         final String authority = uri.getAuthority();
   5924         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
   5925         if (pi == null) {
   5926             Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
   5927             return;
   5928         }
   5929 
   5930         final UriPermission perm = findOrCreateUriPermissionLocked(
   5931                 pi.packageName, targetPkg, targetUid, uri);
   5932         perm.grantModes(modeFlags, persistable, owner);
   5933     }
   5934 
   5935     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
   5936             int modeFlags, UriPermissionOwner owner) {
   5937         if (targetPkg == null) {
   5938             throw new NullPointerException("targetPkg");
   5939         }
   5940 
   5941         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   5942         if (targetUid < 0) {
   5943             return;
   5944         }
   5945 
   5946         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   5947     }
   5948 
   5949     static class NeededUriGrants extends ArrayList<Uri> {
   5950         final String targetPkg;
   5951         final int targetUid;
   5952         final int flags;
   5953 
   5954         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   5955             this.targetPkg = targetPkg;
   5956             this.targetUid = targetUid;
   5957             this.flags = flags;
   5958         }
   5959     }
   5960 
   5961     /**
   5962      * Like checkGrantUriPermissionLocked, but takes an Intent.
   5963      */
   5964     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   5965             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
   5966         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5967                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   5968                 + " clip=" + (intent != null ? intent.getClipData() : null)
   5969                 + " from " + intent + "; flags=0x"
   5970                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   5971 
   5972         if (targetPkg == null) {
   5973             throw new NullPointerException("targetPkg");
   5974         }
   5975 
   5976         if (intent == null) {
   5977             return null;
   5978         }
   5979         Uri data = intent.getData();
   5980         ClipData clip = intent.getClipData();
   5981         if (data == null && clip == null) {
   5982             return null;
   5983         }
   5984 
   5985         if (data != null) {
   5986             int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   5987                 mode, needed != null ? needed.targetUid : -1);
   5988             if (targetUid > 0) {
   5989                 if (needed == null) {
   5990                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   5991                 }
   5992                 needed.add(data);
   5993             }
   5994         }
   5995         if (clip != null) {
   5996             for (int i=0; i<clip.getItemCount(); i++) {
   5997                 Uri uri = clip.getItemAt(i).getUri();
   5998                 if (uri != null) {
   5999                     int targetUid = -1;
   6000                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
   6001                             mode, needed != null ? needed.targetUid : -1);
   6002                     if (targetUid > 0) {
   6003                         if (needed == null) {
   6004                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   6005                         }
   6006                         needed.add(uri);
   6007                     }
   6008                 } else {
   6009                     Intent clipIntent = clip.getItemAt(i).getIntent();
   6010                     if (clipIntent != null) {
   6011                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   6012                                 callingUid, targetPkg, clipIntent, mode, needed);
   6013                         if (newNeeded != null) {
   6014                             needed = newNeeded;
   6015                         }
   6016                     }
   6017                 }
   6018             }
   6019         }
   6020 
   6021         return needed;
   6022     }
   6023 
   6024     /**
   6025      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   6026      */
   6027     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   6028             UriPermissionOwner owner) {
   6029         if (needed != null) {
   6030             for (int i=0; i<needed.size(); i++) {
   6031                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   6032                         needed.get(i), needed.flags, owner);
   6033             }
   6034         }
   6035     }
   6036 
   6037     void grantUriPermissionFromIntentLocked(int callingUid,
   6038             String targetPkg, Intent intent, UriPermissionOwner owner) {
   6039         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   6040                 intent, intent != null ? intent.getFlags() : 0, null);
   6041         if (needed == null) {
   6042             return;
   6043         }
   6044 
   6045         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   6046     }
   6047 
   6048     @Override
   6049     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   6050             Uri uri, int modeFlags) {
   6051         enforceNotIsolatedCaller("grantUriPermission");
   6052         synchronized(this) {
   6053             final ProcessRecord r = getRecordForAppLocked(caller);
   6054             if (r == null) {
   6055                 throw new SecurityException("Unable to find app for caller "
   6056                         + caller
   6057                         + " when granting permission to uri " + uri);
   6058             }
   6059             if (targetPkg == null) {
   6060                 throw new IllegalArgumentException("null target");
   6061             }
   6062             if (uri == null) {
   6063                 throw new IllegalArgumentException("null uri");
   6064             }
   6065 
   6066             // Persistable only supported through Intents
   6067             Preconditions.checkFlagsArgument(modeFlags,
   6068                     Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6069 
   6070             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
   6071                     null);
   6072         }
   6073     }
   6074 
   6075     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   6076         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   6077                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   6078             ArrayMap<Uri, UriPermission> perms
   6079                     = mGrantedUriPermissions.get(perm.targetUid);
   6080             if (perms != null) {
   6081                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6082                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   6083                 perms.remove(perm.uri);
   6084                 if (perms.size() == 0) {
   6085                     mGrantedUriPermissions.remove(perm.targetUid);
   6086                 }
   6087             }
   6088         }
   6089     }
   6090 
   6091     private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
   6092         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
   6093 
   6094         final IPackageManager pm = AppGlobals.getPackageManager();
   6095         final String authority = uri.getAuthority();
   6096         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
   6097         if (pi == null) {
   6098             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   6099             return;
   6100         }
   6101 
   6102         // Does the caller have this permission on the URI?
   6103         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   6104             // Right now, if you are not the original owner of the permission,
   6105             // you are not allowed to revoke it.
   6106             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   6107                 throw new SecurityException("Uid " + callingUid
   6108                         + " does not have permission to uri " + uri);
   6109             //}
   6110         }
   6111 
   6112         boolean persistChanged = false;
   6113 
   6114         // Go through all of the permissions and remove any that match.
   6115         final List<String> SEGMENTS = uri.getPathSegments();
   6116         if (SEGMENTS != null) {
   6117             final int NS = SEGMENTS.size();
   6118             int N = mGrantedUriPermissions.size();
   6119             for (int i=0; i<N; i++) {
   6120                 ArrayMap<Uri, UriPermission> perms
   6121                         = mGrantedUriPermissions.valueAt(i);
   6122                 Iterator<UriPermission> it = perms.values().iterator();
   6123             toploop:
   6124                 while (it.hasNext()) {
   6125                     UriPermission perm = it.next();
   6126                     Uri targetUri = perm.uri;
   6127                     if (!authority.equals(targetUri.getAuthority())) {
   6128                         continue;
   6129                     }
   6130                     List<String> targetSegments = targetUri.getPathSegments();
   6131                     if (targetSegments == null) {
   6132                         continue;
   6133                     }
   6134                     if (targetSegments.size() < NS) {
   6135                         continue;
   6136                     }
   6137                     for (int j=0; j<NS; j++) {
   6138                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   6139                             continue toploop;
   6140                         }
   6141                     }
   6142                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6143                             "Revoking " + perm.targetUid + " permission to " + perm.uri);
   6144                     persistChanged |= perm.clearModes(modeFlags, true);
   6145                     if (perm.modeFlags == 0) {
   6146                         it.remove();
   6147                     }
   6148                 }
   6149                 if (perms.size() == 0) {
   6150                     mGrantedUriPermissions.remove(
   6151                             mGrantedUriPermissions.keyAt(i));
   6152                     N--;
   6153                     i--;
   6154                 }
   6155             }
   6156         }
   6157 
   6158         if (persistChanged) {
   6159             schedulePersistUriGrants();
   6160         }
   6161     }
   6162 
   6163     @Override
   6164     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   6165             int modeFlags) {
   6166         enforceNotIsolatedCaller("revokeUriPermission");
   6167         synchronized(this) {
   6168             final ProcessRecord r = getRecordForAppLocked(caller);
   6169             if (r == null) {
   6170                 throw new SecurityException("Unable to find app for caller "
   6171                         + caller
   6172                         + " when revoking permission to uri " + uri);
   6173             }
   6174             if (uri == null) {
   6175                 Slog.w(TAG, "revokeUriPermission: null uri");
   6176                 return;
   6177             }
   6178 
   6179             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6180                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6181             if (modeFlags == 0) {
   6182                 return;
   6183             }
   6184 
   6185             final IPackageManager pm = AppGlobals.getPackageManager();
   6186             final String authority = uri.getAuthority();
   6187             final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
   6188             if (pi == null) {
   6189                 Slog.w(TAG, "No content provider found for permission revoke: "
   6190                         + uri.toSafeString());
   6191                 return;
   6192             }
   6193 
   6194             revokeUriPermissionLocked(r.uid, uri, modeFlags);
   6195         }
   6196     }
   6197 
   6198     /**
   6199      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   6200      * given package.
   6201      *
   6202      * @param packageName Package name to match, or {@code null} to apply to all
   6203      *            packages.
   6204      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   6205      *            to all users.
   6206      * @param persistable If persistable grants should be removed.
   6207      */
   6208     private void removeUriPermissionsForPackageLocked(
   6209             String packageName, int userHandle, boolean persistable) {
   6210         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   6211             throw new IllegalArgumentException("Must narrow by either package or user");
   6212         }
   6213 
   6214         boolean persistChanged = false;
   6215 
   6216         final int size = mGrantedUriPermissions.size();
   6217         for (int i = 0; i < size; i++) {
   6218             // Only inspect grants matching user
   6219             if (userHandle == UserHandle.USER_ALL
   6220                     || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
   6221                 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
   6222                         .values().iterator();
   6223                 while (it.hasNext()) {
   6224                     final UriPermission perm = it.next();
   6225 
   6226                     // Only inspect grants matching package
   6227                     if (packageName == null || perm.sourcePkg.equals(packageName)
   6228                             || perm.targetPkg.equals(packageName)) {
   6229                         persistChanged |= perm.clearModes(~0, persistable);
   6230 
   6231                         // Only remove when no modes remain; any persisted grants
   6232                         // will keep this alive.
   6233                         if (perm.modeFlags == 0) {
   6234                             it.remove();
   6235                         }
   6236                     }
   6237                 }
   6238             }
   6239         }
   6240 
   6241         if (persistChanged) {
   6242             schedulePersistUriGrants();
   6243         }
   6244     }
   6245 
   6246     @Override
   6247     public IBinder newUriPermissionOwner(String name) {
   6248         enforceNotIsolatedCaller("newUriPermissionOwner");
   6249         synchronized(this) {
   6250             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   6251             return owner.getExternalTokenLocked();
   6252         }
   6253     }
   6254 
   6255     @Override
   6256     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   6257             Uri uri, int modeFlags) {
   6258         synchronized(this) {
   6259             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   6260             if (owner == null) {
   6261                 throw new IllegalArgumentException("Unknown owner: " + token);
   6262             }
   6263             if (fromUid != Binder.getCallingUid()) {
   6264                 if (Binder.getCallingUid() != Process.myUid()) {
   6265                     // Only system code can grant URI permissions on behalf
   6266                     // of other users.
   6267                     throw new SecurityException("nice try");
   6268                 }
   6269             }
   6270             if (targetPkg == null) {
   6271                 throw new IllegalArgumentException("null target");
   6272             }
   6273             if (uri == null) {
   6274                 throw new IllegalArgumentException("null uri");
   6275             }
   6276 
   6277             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   6278         }
   6279     }
   6280 
   6281     @Override
   6282     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   6283         synchronized(this) {
   6284             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   6285             if (owner == null) {
   6286                 throw new IllegalArgumentException("Unknown owner: " + token);
   6287             }
   6288 
   6289             if (uri == null) {
   6290                 owner.removeUriPermissionsLocked(mode);
   6291             } else {
   6292                 owner.removeUriPermissionLocked(uri, mode);
   6293             }
   6294         }
   6295     }
   6296 
   6297     private void schedulePersistUriGrants() {
   6298         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   6299             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   6300                     10 * DateUtils.SECOND_IN_MILLIS);
   6301         }
   6302     }
   6303 
   6304     private void writeGrantedUriPermissions() {
   6305         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
   6306 
   6307         // Snapshot permissions so we can persist without lock
   6308         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   6309         synchronized (this) {
   6310             final int size = mGrantedUriPermissions.size();
   6311             for (int i = 0 ; i < size; i++) {
   6312                 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
   6313                     if (perm.persistedModeFlags != 0) {
   6314                         persist.add(perm.snapshot());
   6315                     }
   6316                 }
   6317             }
   6318         }
   6319 
   6320         FileOutputStream fos = null;
   6321         try {
   6322             fos = mGrantFile.startWrite();
   6323 
   6324             XmlSerializer out = new FastXmlSerializer();
   6325             out.setOutput(fos, "utf-8");
   6326             out.startDocument(null, true);
   6327             out.startTag(null, TAG_URI_GRANTS);
   6328             for (UriPermission.Snapshot perm : persist) {
   6329                 out.startTag(null, TAG_URI_GRANT);
   6330                 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
   6331                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   6332                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   6333                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
   6334                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   6335                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   6336                 out.endTag(null, TAG_URI_GRANT);
   6337             }
   6338             out.endTag(null, TAG_URI_GRANTS);
   6339             out.endDocument();
   6340 
   6341             mGrantFile.finishWrite(fos);
   6342         } catch (IOException e) {
   6343             if (fos != null) {
   6344                 mGrantFile.failWrite(fos);
   6345             }
   6346         }
   6347     }
   6348 
   6349     private void readGrantedUriPermissionsLocked() {
   6350         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
   6351 
   6352         final long now = System.currentTimeMillis();
   6353 
   6354         FileInputStream fis = null;
   6355         try {
   6356             fis = mGrantFile.openRead();
   6357             final XmlPullParser in = Xml.newPullParser();
   6358             in.setInput(fis, null);
   6359 
   6360             int type;
   6361             while ((type = in.next()) != END_DOCUMENT) {
   6362                 final String tag = in.getName();
   6363                 if (type == START_TAG) {
   6364                     if (TAG_URI_GRANT.equals(tag)) {
   6365                         final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
   6366                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   6367                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   6368                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   6369                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   6370                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   6371 
   6372                         // Sanity check that provider still belongs to source package
   6373                         final ProviderInfo pi = getProviderInfoLocked(
   6374                                 uri.getAuthority(), userHandle);
   6375                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   6376                             int targetUid = -1;
   6377                             try {
   6378                                 targetUid = AppGlobals.getPackageManager()
   6379                                         .getPackageUid(targetPkg, userHandle);
   6380                             } catch (RemoteException e) {
   6381                             }
   6382                             if (targetUid != -1) {
   6383                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   6384                                         sourcePkg, targetPkg, targetUid, uri);
   6385                                 perm.initPersistedModes(modeFlags, createdTime);
   6386                             }
   6387                         } else {
   6388                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   6389                                     + " but instead found " + pi);
   6390                         }
   6391                     }
   6392                 }
   6393             }
   6394         } catch (FileNotFoundException e) {
   6395             // Missing grants is okay
   6396         } catch (IOException e) {
   6397             Log.wtf(TAG, "Failed reading Uri grants", e);
   6398         } catch (XmlPullParserException e) {
   6399             Log.wtf(TAG, "Failed reading Uri grants", e);
   6400         } finally {
   6401             IoUtils.closeQuietly(fis);
   6402         }
   6403     }
   6404 
   6405     @Override
   6406     public void takePersistableUriPermission(Uri uri, int modeFlags) {
   6407         enforceNotIsolatedCaller("takePersistableUriPermission");
   6408 
   6409         Preconditions.checkFlagsArgument(modeFlags,
   6410                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6411 
   6412         synchronized (this) {
   6413             final int callingUid = Binder.getCallingUid();
   6414             final UriPermission perm = findUriPermissionLocked(callingUid, uri);
   6415             if (perm == null) {
   6416                 throw new SecurityException("No permission grant found for UID " + callingUid
   6417                         + " and Uri " + uri.toSafeString());
   6418             }
   6419 
   6420             boolean persistChanged = perm.takePersistableModes(modeFlags);
   6421             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   6422 
   6423             if (persistChanged) {
   6424                 schedulePersistUriGrants();
   6425             }
   6426         }
   6427     }
   6428 
   6429     @Override
   6430     public void releasePersistableUriPermission(Uri uri, int modeFlags) {
   6431         enforceNotIsolatedCaller("releasePersistableUriPermission");
   6432 
   6433         Preconditions.checkFlagsArgument(modeFlags,
   6434                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6435 
   6436         synchronized (this) {
   6437             final int callingUid = Binder.getCallingUid();
   6438 
   6439             final UriPermission perm = findUriPermissionLocked(callingUid, uri);
   6440             if (perm == null) {
   6441                 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
   6442                         + uri.toSafeString());
   6443                 return;
   6444             }
   6445 
   6446             final boolean persistChanged = perm.releasePersistableModes(modeFlags);
   6447             removeUriPermissionIfNeededLocked(perm);
   6448             if (persistChanged) {
   6449                 schedulePersistUriGrants();
   6450             }
   6451         }
   6452     }
   6453 
   6454     /**
   6455      * Prune any older {@link UriPermission} for the given UID until outstanding
   6456      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   6457      *
   6458      * @return if any mutations occured that require persisting.
   6459      */
   6460     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   6461         final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   6462         if (perms == null) return false;
   6463         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   6464 
   6465         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   6466         for (UriPermission perm : perms.values()) {
   6467             if (perm.persistedModeFlags != 0) {
   6468                 persisted.add(perm);
   6469             }
   6470         }
   6471 
   6472         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   6473         if (trimCount <= 0) return false;
   6474 
   6475         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   6476         for (int i = 0; i < trimCount; i++) {
   6477             final UriPermission perm = persisted.get(i);
   6478 
   6479             if (DEBUG_URI_PERMISSION) {
   6480                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
   6481             }
   6482 
   6483             perm.releasePersistableModes(~0);
   6484             removeUriPermissionIfNeededLocked(perm);
   6485         }
   6486 
   6487         return true;
   6488     }
   6489 
   6490     @Override
   6491     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   6492             String packageName, boolean incoming) {
   6493         enforceNotIsolatedCaller("getPersistedUriPermissions");
   6494         Preconditions.checkNotNull(packageName, "packageName");
   6495 
   6496         final int callingUid = Binder.getCallingUid();
   6497         final IPackageManager pm = AppGlobals.getPackageManager();
   6498         try {
   6499             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
   6500             if (packageUid != callingUid) {
   6501                 throw new SecurityException(
   6502                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   6503             }
   6504         } catch (RemoteException e) {
   6505             throw new SecurityException("Failed to verify package name ownership");
   6506         }
   6507 
   6508         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   6509         synchronized (this) {
   6510             if (incoming) {
   6511                 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   6512                 if (perms == null) {
   6513                     Slog.w(TAG, "No permission grants found for " + packageName);
   6514                 } else {
   6515                     final int size = perms.size();
   6516                     for (int i = 0; i < size; i++) {
   6517                         final UriPermission perm = perms.valueAt(i);
   6518                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   6519                             result.add(perm.buildPersistedPublicApiObject());
   6520                         }
   6521                     }
   6522                 }
   6523             } else {
   6524                 final int size = mGrantedUriPermissions.size();
   6525                 for (int i = 0; i < size; i++) {
   6526                     final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   6527                     final int permsSize = perms.size();
   6528                     for (int j = 0; j < permsSize; j++) {
   6529                         final UriPermission perm = perms.valueAt(j);
   6530                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   6531                             result.add(perm.buildPersistedPublicApiObject());
   6532                         }
   6533                     }
   6534                 }
   6535             }
   6536         }
   6537         return new ParceledListSlice<android.content.UriPermission>(result);
   6538     }
   6539 
   6540     @Override
   6541     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   6542         synchronized (this) {
   6543             ProcessRecord app =
   6544                 who != null ? getRecordForAppLocked(who) : null;
   6545             if (app == null) return;
   6546 
   6547             Message msg = Message.obtain();
   6548             msg.what = WAIT_FOR_DEBUGGER_MSG;
   6549             msg.obj = app;
   6550             msg.arg1 = waiting ? 1 : 0;
   6551             mHandler.sendMessage(msg);
   6552         }
   6553     }
   6554 
   6555     @Override
   6556     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   6557         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   6558         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   6559         outInfo.availMem = Process.getFreeMemory();
   6560         outInfo.totalMem = Process.getTotalMemory();
   6561         outInfo.threshold = homeAppMem;
   6562         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   6563         outInfo.hiddenAppThreshold = cachedAppMem;
   6564         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   6565                 ProcessList.SERVICE_ADJ);
   6566         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   6567                 ProcessList.VISIBLE_APP_ADJ);
   6568         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   6569                 ProcessList.FOREGROUND_APP_ADJ);
   6570     }
   6571 
   6572     // =========================================================
   6573     // TASK MANAGEMENT
   6574     // =========================================================
   6575 
   6576     @Override
   6577     public List<RunningTaskInfo> getTasks(int maxNum, int flags,
   6578                          IThumbnailReceiver receiver) {
   6579         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   6580 
   6581         PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
   6582         ActivityRecord topRecord = null;
   6583 
   6584         synchronized(this) {
   6585             if (localLOGV) Slog.v(
   6586                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   6587                 + ", receiver=" + receiver);
   6588 
   6589             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   6590                     != PackageManager.PERMISSION_GRANTED) {
   6591                 if (receiver != null) {
   6592                     // If the caller wants to wait for pending thumbnails,
   6593                     // it ain't gonna get them.
   6594                     try {
   6595                         receiver.finished();
   6596                     } catch (RemoteException ex) {
   6597                     }
   6598                 }
   6599                 String msg = "Permission Denial: getTasks() from pid="
   6600                         + Binder.getCallingPid()
   6601                         + ", uid=" + Binder.getCallingUid()
   6602                         + " requires " + android.Manifest.permission.GET_TASKS;
   6603                 Slog.w(TAG, msg);
   6604                 throw new SecurityException(msg);
   6605             }
   6606 
   6607             // TODO: Improve with MRU list from all ActivityStacks.
   6608             topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
   6609 
   6610             if (!pending.pendingRecords.isEmpty()) {
   6611                 mPendingThumbnails.add(pending);
   6612             }
   6613         }
   6614 
   6615         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   6616 
   6617         if (topRecord != null) {
   6618             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   6619             try {
   6620                 IApplicationThread topThumbnail = topRecord.app.thread;
   6621                 topThumbnail.requestThumbnail(topRecord.appToken);
   6622             } catch (Exception e) {
   6623                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   6624                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   6625             }
   6626         }
   6627 
   6628         if (pending == null && receiver != null) {
   6629             // In this case all thumbnails were available and the client
   6630             // is being asked to be told when the remaining ones come in...
   6631             // which is unusually, since the top-most currently running
   6632             // activity should never have a canned thumbnail!  Oh well.
   6633             try {
   6634                 receiver.finished();
   6635             } catch (RemoteException ex) {
   6636             }
   6637         }
   6638 
   6639         return list;
   6640     }
   6641 
   6642     TaskRecord getMostRecentTask() {
   6643         return mRecentTasks.get(0);
   6644     }
   6645 
   6646     @Override
   6647     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   6648             int flags, int userId) {
   6649         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6650                 false, true, "getRecentTasks", null);
   6651 
   6652         synchronized (this) {
   6653             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   6654                     "getRecentTasks()");
   6655             final boolean detailed = checkCallingPermission(
   6656                     android.Manifest.permission.GET_DETAILED_TASKS)
   6657                     == PackageManager.PERMISSION_GRANTED;
   6658 
   6659             IPackageManager pm = AppGlobals.getPackageManager();
   6660 
   6661             final int N = mRecentTasks.size();
   6662             ArrayList<ActivityManager.RecentTaskInfo> res
   6663                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   6664                             maxNum < N ? maxNum : N);
   6665             for (int i=0; i<N && maxNum > 0; i++) {
   6666                 TaskRecord tr = mRecentTasks.get(i);
   6667                 // Only add calling user's recent tasks
   6668                 if (tr.userId != userId) continue;
   6669                 // Return the entry if desired by the caller.  We always return
   6670                 // the first entry, because callers always expect this to be the
   6671                 // foreground app.  We may filter others if the caller has
   6672                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   6673                 // we should exclude the entry.
   6674 
   6675                 if (i == 0
   6676                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   6677                         || (tr.intent == null)
   6678                         || ((tr.intent.getFlags()
   6679                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   6680                     ActivityManager.RecentTaskInfo rti
   6681                             = new ActivityManager.RecentTaskInfo();
   6682                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   6683                     rti.persistentId = tr.taskId;
   6684                     rti.baseIntent = new Intent(
   6685                             tr.intent != null ? tr.intent : tr.affinityIntent);
   6686                     if (!detailed) {
   6687                         rti.baseIntent.replaceExtras((Bundle)null);
   6688                     }
   6689                     rti.origActivity = tr.origActivity;
   6690                     rti.description = tr.lastDescription;
   6691                     rti.stackId = tr.stack.mStackId;
   6692 
   6693                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   6694                         // Check whether this activity is currently available.
   6695                         try {
   6696                             if (rti.origActivity != null) {
   6697                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
   6698                                         == null) {
   6699                                     continue;
   6700                                 }
   6701                             } else if (rti.baseIntent != null) {
   6702                                 if (pm.queryIntentActivities(rti.baseIntent,
   6703                                         null, 0, userId) == null) {
   6704                                     continue;
   6705                                 }
   6706                             }
   6707                         } catch (RemoteException e) {
   6708                             // Will never happen.
   6709                         }
   6710                     }
   6711 
   6712                     res.add(rti);
   6713                     maxNum--;
   6714                 }
   6715             }
   6716             return res;
   6717         }
   6718     }
   6719 
   6720     private TaskRecord recentTaskForIdLocked(int id) {
   6721         final int N = mRecentTasks.size();
   6722             for (int i=0; i<N; i++) {
   6723                 TaskRecord tr = mRecentTasks.get(i);
   6724                 if (tr.taskId == id) {
   6725                     return tr;
   6726                 }
   6727             }
   6728             return null;
   6729     }
   6730 
   6731     @Override
   6732     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   6733         synchronized (this) {
   6734             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   6735                     "getTaskThumbnails()");
   6736             TaskRecord tr = recentTaskForIdLocked(id);
   6737             if (tr != null) {
   6738                 return tr.getTaskThumbnailsLocked();
   6739             }
   6740         }
   6741         return null;
   6742     }
   6743 
   6744     @Override
   6745     public Bitmap getTaskTopThumbnail(int id) {
   6746         synchronized (this) {
   6747             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   6748                     "getTaskTopThumbnail()");
   6749             TaskRecord tr = recentTaskForIdLocked(id);
   6750             if (tr != null) {
   6751                 return tr.getTaskTopThumbnailLocked();
   6752             }
   6753         }
   6754         return null;
   6755     }
   6756 
   6757     @Override
   6758     public boolean removeSubTask(int taskId, int subTaskIndex) {
   6759         synchronized (this) {
   6760             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   6761                     "removeSubTask()");
   6762             long ident = Binder.clearCallingIdentity();
   6763             try {
   6764                 TaskRecord tr = recentTaskForIdLocked(taskId);
   6765                 if (tr != null) {
   6766                     return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
   6767                 }
   6768                 return false;
   6769             } finally {
   6770                 Binder.restoreCallingIdentity(ident);
   6771             }
   6772         }
   6773     }
   6774 
   6775     private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
   6776         if (!pr.killedByAm) {
   6777             Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
   6778             EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
   6779                     pr.processName, pr.setAdj, reason);
   6780             pr.killedByAm = true;
   6781             Process.killProcessQuiet(pr.pid);
   6782         }
   6783     }
   6784 
   6785     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   6786         tr.disposeThumbnail();
   6787         mRecentTasks.remove(tr);
   6788         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   6789         Intent baseIntent = new Intent(
   6790                 tr.intent != null ? tr.intent : tr.affinityIntent);
   6791         ComponentName component = baseIntent.getComponent();
   6792         if (component == null) {
   6793             Slog.w(TAG, "Now component for base intent of task: " + tr);
   6794             return;
   6795         }
   6796 
   6797         // Find any running services associated with this app.
   6798         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
   6799 
   6800         if (killProcesses) {
   6801             // Find any running processes associated with this app.
   6802             final String pkg = component.getPackageName();
   6803             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   6804             ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   6805             for (int i=0; i<pmap.size(); i++) {
   6806                 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   6807                 for (int j=0; j<uids.size(); j++) {
   6808                     ProcessRecord proc = uids.valueAt(j);
   6809                     if (proc.userId != tr.userId) {
   6810                         continue;
   6811                     }
   6812                     if (!proc.pkgList.containsKey(pkg)) {
   6813                         continue;
   6814                     }
   6815                     procs.add(proc);
   6816                 }
   6817             }
   6818 
   6819             // Kill the running processes.
   6820             for (int i=0; i<procs.size(); i++) {
   6821                 ProcessRecord pr = procs.get(i);
   6822                 if (pr == mHomeProcess) {
   6823                     // Don't kill the home process along with tasks from the same package.
   6824                     continue;
   6825                 }
   6826                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   6827                     killUnneededProcessLocked(pr, "remove task");
   6828                 } else {
   6829                     pr.waitingToKill = "remove task";
   6830                 }
   6831             }
   6832         }
   6833     }
   6834 
   6835     @Override
   6836     public boolean removeTask(int taskId, int flags) {
   6837         synchronized (this) {
   6838             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   6839                     "removeTask()");
   6840             long ident = Binder.clearCallingIdentity();
   6841             try {
   6842                 TaskRecord tr = recentTaskForIdLocked(taskId);
   6843                 if (tr != null) {
   6844                     ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
   6845                     if (r != null) {
   6846                         cleanUpRemovedTaskLocked(tr, flags);
   6847                         return true;
   6848                     }
   6849                     if (tr.mActivities.size() == 0) {
   6850                         // Caller is just removing a recent task that is
   6851                         // not actively running.  That is easy!
   6852                         cleanUpRemovedTaskLocked(tr, flags);
   6853                         return true;
   6854                     }
   6855                     Slog.w(TAG, "removeTask: task " + taskId
   6856                             + " does not have activities to remove, "
   6857                             + " but numActivities=" + tr.numActivities
   6858                             + ": " + tr);
   6859                 }
   6860             } finally {
   6861                 Binder.restoreCallingIdentity(ident);
   6862             }
   6863         }
   6864         return false;
   6865     }
   6866 
   6867     /**
   6868      * TODO: Add mController hook
   6869      */
   6870     @Override
   6871     public void moveTaskToFront(int task, int flags, Bundle options) {
   6872         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6873                 "moveTaskToFront()");
   6874 
   6875         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
   6876         synchronized(this) {
   6877             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6878                     Binder.getCallingUid(), "Task to front")) {
   6879                 ActivityOptions.abort(options);
   6880                 return;
   6881             }
   6882             final long origId = Binder.clearCallingIdentity();
   6883             try {
   6884                 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
   6885             } finally {
   6886                 Binder.restoreCallingIdentity(origId);
   6887             }
   6888             ActivityOptions.abort(options);
   6889         }
   6890     }
   6891 
   6892     @Override
   6893     public void moveTaskToBack(int taskId) {
   6894         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6895                 "moveTaskToBack()");
   6896 
   6897         synchronized(this) {
   6898             TaskRecord tr = recentTaskForIdLocked(taskId);
   6899             if (tr != null) {
   6900                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
   6901                 ActivityStack stack = tr.stack;
   6902                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
   6903                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6904                             Binder.getCallingUid(), "Task to back")) {
   6905                         return;
   6906                     }
   6907                 }
   6908                 final long origId = Binder.clearCallingIdentity();
   6909                 try {
   6910                     stack.moveTaskToBackLocked(taskId, null);
   6911                 } finally {
   6912                     Binder.restoreCallingIdentity(origId);
   6913                 }
   6914             }
   6915         }
   6916     }
   6917 
   6918     /**
   6919      * Moves an activity, and all of the other activities within the same task, to the bottom
   6920      * of the history stack.  The activity's order within the task is unchanged.
   6921      *
   6922      * @param token A reference to the activity we wish to move
   6923      * @param nonRoot If false then this only works if the activity is the root
   6924      *                of a task; if true it will work for any activity in a task.
   6925      * @return Returns true if the move completed, false if not.
   6926      */
   6927     @Override
   6928     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   6929         enforceNotIsolatedCaller("moveActivityTaskToBack");
   6930         synchronized(this) {
   6931             final long origId = Binder.clearCallingIdentity();
   6932             int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   6933             if (taskId >= 0) {
   6934                 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
   6935             }
   6936             Binder.restoreCallingIdentity(origId);
   6937         }
   6938         return false;
   6939     }
   6940 
   6941     @Override
   6942     public void moveTaskBackwards(int task) {
   6943         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   6944                 "moveTaskBackwards()");
   6945 
   6946         synchronized(this) {
   6947             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   6948                     Binder.getCallingUid(), "Task backwards")) {
   6949                 return;
   6950             }
   6951             final long origId = Binder.clearCallingIdentity();
   6952             moveTaskBackwardsLocked(task);
   6953             Binder.restoreCallingIdentity(origId);
   6954         }
   6955     }
   6956 
   6957     private final void moveTaskBackwardsLocked(int task) {
   6958         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   6959     }
   6960 
   6961     @Override
   6962     public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
   6963         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   6964                 "createStack()");
   6965         if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
   6966                 relativeStackBoxId + " position=" + position + " weight=" + weight);
   6967         synchronized (this) {
   6968             long ident = Binder.clearCallingIdentity();
   6969             try {
   6970                 int stackId = mStackSupervisor.createStack();
   6971                 mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
   6972                 if (taskId > 0) {
   6973                     moveTaskToStack(taskId, stackId, true);
   6974                 }
   6975                 return stackId;
   6976             } finally {
   6977                 Binder.restoreCallingIdentity(ident);
   6978             }
   6979         }
   6980     }
   6981 
   6982     @Override
   6983     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   6984         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   6985                 "moveTaskToStack()");
   6986         if (stackId == HOME_STACK_ID) {
   6987             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
   6988                     new RuntimeException("here").fillInStackTrace());
   6989         }
   6990         synchronized (this) {
   6991             long ident = Binder.clearCallingIdentity();
   6992             try {
   6993                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
   6994                         + stackId + " toTop=" + toTop);
   6995                 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
   6996             } finally {
   6997                 Binder.restoreCallingIdentity(ident);
   6998             }
   6999         }
   7000     }
   7001 
   7002     @Override
   7003     public void resizeStackBox(int stackBoxId, float weight) {
   7004         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7005                 "resizeStackBox()");
   7006         long ident = Binder.clearCallingIdentity();
   7007         try {
   7008             mWindowManager.resizeStackBox(stackBoxId, weight);
   7009         } finally {
   7010             Binder.restoreCallingIdentity(ident);
   7011         }
   7012     }
   7013 
   7014     private ArrayList<StackInfo> getStacks() {
   7015         synchronized (this) {
   7016             ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
   7017             ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
   7018             for (ActivityStack stack : stacks) {
   7019                 ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
   7020                 int stackId = stack.mStackId;
   7021                 stackInfo.stackId = stackId;
   7022                 stackInfo.bounds = mWindowManager.getStackBounds(stackId);
   7023                 ArrayList<TaskRecord> tasks = stack.getAllTasks();
   7024                 final int numTasks = tasks.size();
   7025                 int[] taskIds = new int[numTasks];
   7026                 String[] taskNames = new String[numTasks];
   7027                 for (int i = 0; i < numTasks; ++i) {
   7028                     final TaskRecord task = tasks.get(i);
   7029                     taskIds[i] = task.taskId;
   7030                     taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
   7031                             : task.realActivity != null ? task.realActivity.flattenToString()
   7032                             : task.getTopActivity() != null ? task.getTopActivity().packageName
   7033                             : "unknown";
   7034                 }
   7035                 stackInfo.taskIds = taskIds;
   7036                 stackInfo.taskNames = taskNames;
   7037                 list.add(stackInfo);
   7038             }
   7039             return list;
   7040         }
   7041     }
   7042 
   7043     private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
   7044         final int stackId = stackBoxInfo.stackId;
   7045         if (stackId >= 0) {
   7046             for (StackInfo stackInfo : stackInfos) {
   7047                 if (stackId == stackInfo.stackId) {
   7048                     stackBoxInfo.stack = stackInfo;
   7049                     stackInfos.remove(stackInfo);
   7050                     return;
   7051                 }
   7052             }
   7053         } else {
   7054             addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
   7055             addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
   7056         }
   7057     }
   7058 
   7059     @Override
   7060     public List<StackBoxInfo> getStackBoxes() {
   7061         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7062                 "getStackBoxes()");
   7063         long ident = Binder.clearCallingIdentity();
   7064         try {
   7065             List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
   7066             synchronized (this) {
   7067                 List<StackInfo> stackInfos = getStacks();
   7068                 for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
   7069                     addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
   7070                 }
   7071             }
   7072             return stackBoxInfos;
   7073         } finally {
   7074             Binder.restoreCallingIdentity(ident);
   7075         }
   7076     }
   7077 
   7078     @Override
   7079     public StackBoxInfo getStackBoxInfo(int stackBoxId) {
   7080         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7081                 "getStackBoxInfo()");
   7082         long ident = Binder.clearCallingIdentity();
   7083         try {
   7084             List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
   7085             StackBoxInfo info = null;
   7086             synchronized (this) {
   7087                 List<StackInfo> stackInfos = getStacks();
   7088                 for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
   7089                     addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
   7090                     if (stackBoxInfo.stackBoxId == stackBoxId) {
   7091                         info = stackBoxInfo;
   7092                     }
   7093                 }
   7094             }
   7095             return info;
   7096         } finally {
   7097             Binder.restoreCallingIdentity(ident);
   7098         }
   7099     }
   7100 
   7101     @Override
   7102     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   7103         synchronized(this) {
   7104             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   7105         }
   7106     }
   7107 
   7108     // =========================================================
   7109     // THUMBNAILS
   7110     // =========================================================
   7111 
   7112     public void reportThumbnail(IBinder token,
   7113             Bitmap thumbnail, CharSequence description) {
   7114         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   7115         final long origId = Binder.clearCallingIdentity();
   7116         sendPendingThumbnail(null, token, thumbnail, description, true);
   7117         Binder.restoreCallingIdentity(origId);
   7118     }
   7119 
   7120     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   7121             Bitmap thumbnail, CharSequence description, boolean always) {
   7122         TaskRecord task;
   7123         ArrayList<PendingThumbnailsRecord> receivers = null;
   7124 
   7125         //System.out.println("Send pending thumbnail: " + r);
   7126 
   7127         synchronized(this) {
   7128             if (r == null) {
   7129                 r = ActivityRecord.isInStackLocked(token);
   7130                 if (r == null) {
   7131                     return;
   7132                 }
   7133             }
   7134             if (thumbnail == null && r.thumbHolder != null) {
   7135                 thumbnail = r.thumbHolder.lastThumbnail;
   7136                 description = r.thumbHolder.lastDescription;
   7137             }
   7138             if (thumbnail == null && !always) {
   7139                 // If there is no thumbnail, and this entry is not actually
   7140                 // going away, then abort for now and pick up the next
   7141                 // thumbnail we get.
   7142                 return;
   7143             }
   7144             task = r.task;
   7145 
   7146             int N = mPendingThumbnails.size();
   7147             int i=0;
   7148             while (i<N) {
   7149                 PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
   7150                 //System.out.println("Looking in " + pr.pendingRecords);
   7151                 if (pr.pendingRecords.remove(r)) {
   7152                     if (receivers == null) {
   7153                         receivers = new ArrayList<PendingThumbnailsRecord>();
   7154                     }
   7155                     receivers.add(pr);
   7156                     if (pr.pendingRecords.size() == 0) {
   7157                         pr.finished = true;
   7158                         mPendingThumbnails.remove(i);
   7159                         N--;
   7160                         continue;
   7161                     }
   7162                 }
   7163                 i++;
   7164             }
   7165         }
   7166 
   7167         if (receivers != null) {
   7168             final int N = receivers.size();
   7169             for (int i=0; i<N; i++) {
   7170                 try {
   7171                     PendingThumbnailsRecord pr = receivers.get(i);
   7172                     pr.receiver.newThumbnail(
   7173                         task != null ? task.taskId : -1, thumbnail, description);
   7174                     if (pr.finished) {
   7175                         pr.receiver.finished();
   7176                     }
   7177                 } catch (Exception e) {
   7178                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   7179                 }
   7180             }
   7181         }
   7182     }
   7183 
   7184     // =========================================================
   7185     // CONTENT PROVIDERS
   7186     // =========================================================
   7187 
   7188     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   7189         List<ProviderInfo> providers = null;
   7190         try {
   7191             providers = AppGlobals.getPackageManager().
   7192                 queryContentProviders(app.processName, app.uid,
   7193                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   7194         } catch (RemoteException ex) {
   7195         }
   7196         if (DEBUG_MU)
   7197             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   7198         int userId = app.userId;
   7199         if (providers != null) {
   7200             int N = providers.size();
   7201             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   7202             for (int i=0; i<N; i++) {
   7203                 ProviderInfo cpi =
   7204                     (ProviderInfo)providers.get(i);
   7205                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   7206                         cpi.name, cpi.flags);
   7207                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   7208                     // This is a singleton provider, but a user besides the
   7209                     // default user is asking to initialize a process it runs
   7210                     // in...  well, no, it doesn't actually run in this process,
   7211                     // it runs in the process of the default user.  Get rid of it.
   7212                     providers.remove(i);
   7213                     N--;
   7214                     i--;
   7215                     continue;
   7216                 }
   7217 
   7218                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   7219                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   7220                 if (cpr == null) {
   7221                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   7222                     mProviderMap.putProviderByClass(comp, cpr);
   7223                 }
   7224                 if (DEBUG_MU)
   7225                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   7226                 app.pubProviders.put(cpi.name, cpr);
   7227                 app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
   7228                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   7229             }
   7230         }
   7231         return providers;
   7232     }
   7233 
   7234     /**
   7235      * Check if {@link ProcessRecord} has a possible chance at accessing the
   7236      * given {@link ProviderInfo}. Final permission checking is always done
   7237      * in {@link ContentProvider}.
   7238      */
   7239     private final String checkContentProviderPermissionLocked(
   7240             ProviderInfo cpi, ProcessRecord r) {
   7241         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   7242         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   7243         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   7244                 cpi.applicationInfo.uid, cpi.exported)
   7245                 == PackageManager.PERMISSION_GRANTED) {
   7246             return null;
   7247         }
   7248         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   7249                 cpi.applicationInfo.uid, cpi.exported)
   7250                 == PackageManager.PERMISSION_GRANTED) {
   7251             return null;
   7252         }
   7253 
   7254         PathPermission[] pps = cpi.pathPermissions;
   7255         if (pps != null) {
   7256             int i = pps.length;
   7257             while (i > 0) {
   7258                 i--;
   7259                 PathPermission pp = pps[i];
   7260                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   7261                         cpi.applicationInfo.uid, cpi.exported)
   7262                         == PackageManager.PERMISSION_GRANTED) {
   7263                     return null;
   7264                 }
   7265                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   7266                         cpi.applicationInfo.uid, cpi.exported)
   7267                         == PackageManager.PERMISSION_GRANTED) {
   7268                     return null;
   7269                 }
   7270             }
   7271         }
   7272 
   7273         ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   7274         if (perms != null) {
   7275             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   7276                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   7277                     return null;
   7278                 }
   7279             }
   7280         }
   7281 
   7282         String msg;
   7283         if (!cpi.exported) {
   7284             msg = "Permission Denial: opening provider " + cpi.name
   7285                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   7286                     + ", uid=" + callingUid + ") that is not exported from uid "
   7287                     + cpi.applicationInfo.uid;
   7288         } else {
   7289             msg = "Permission Denial: opening provider " + cpi.name
   7290                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   7291                     + ", uid=" + callingUid + ") requires "
   7292                     + cpi.readPermission + " or " + cpi.writePermission;
   7293         }
   7294         Slog.w(TAG, msg);
   7295         return msg;
   7296     }
   7297 
   7298     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   7299             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   7300         if (r != null) {
   7301             for (int i=0; i<r.conProviders.size(); i++) {
   7302                 ContentProviderConnection conn = r.conProviders.get(i);
   7303                 if (conn.provider == cpr) {
   7304                     if (DEBUG_PROVIDER) Slog.v(TAG,
   7305                             "Adding provider requested by "
   7306                             + r.processName + " from process "
   7307                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   7308                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   7309                     if (stable) {
   7310                         conn.stableCount++;
   7311                         conn.numStableIncs++;
   7312                     } else {
   7313                         conn.unstableCount++;
   7314                         conn.numUnstableIncs++;
   7315                     }
   7316                     return conn;
   7317                 }
   7318             }
   7319             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   7320             if (stable) {
   7321                 conn.stableCount = 1;
   7322                 conn.numStableIncs = 1;
   7323             } else {
   7324                 conn.unstableCount = 1;
   7325                 conn.numUnstableIncs = 1;
   7326             }
   7327             cpr.connections.add(conn);
   7328             r.conProviders.add(conn);
   7329             return conn;
   7330         }
   7331         cpr.addExternalProcessHandleLocked(externalProcessToken);
   7332         return null;
   7333     }
   7334 
   7335     boolean decProviderCountLocked(ContentProviderConnection conn,
   7336             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   7337         if (conn != null) {
   7338             cpr = conn.provider;
   7339             if (DEBUG_PROVIDER) Slog.v(TAG,
   7340                     "Removing provider requested by "
   7341                     + conn.client.processName + " from process "
   7342                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   7343                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   7344             if (stable) {
   7345                 conn.stableCount--;
   7346             } else {
   7347                 conn.unstableCount--;
   7348             }
   7349             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   7350                 cpr.connections.remove(conn);
   7351                 conn.client.conProviders.remove(conn);
   7352                 return true;
   7353             }
   7354             return false;
   7355         }
   7356         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   7357         return false;
   7358     }
   7359 
   7360     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   7361             String name, IBinder token, boolean stable, int userId) {
   7362         ContentProviderRecord cpr;
   7363         ContentProviderConnection conn = null;
   7364         ProviderInfo cpi = null;
   7365 
   7366         synchronized(this) {
   7367             ProcessRecord r = null;
   7368             if (caller != null) {
   7369                 r = getRecordForAppLocked(caller);
   7370                 if (r == null) {
   7371                     throw new SecurityException(
   7372                             "Unable to find app for caller " + caller
   7373                           + " (pid=" + Binder.getCallingPid()
   7374                           + ") when getting content provider " + name);
   7375                 }
   7376             }
   7377 
   7378             // First check if this content provider has been published...
   7379             cpr = mProviderMap.getProviderByName(name, userId);
   7380             boolean providerRunning = cpr != null;
   7381             if (providerRunning) {
   7382                 cpi = cpr.info;
   7383                 String msg;
   7384                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   7385                     throw new SecurityException(msg);
   7386                 }
   7387 
   7388                 if (r != null && cpr.canRunHere(r)) {
   7389                     // This provider has been published or is in the process
   7390                     // of being published...  but it is also allowed to run
   7391                     // in the caller's process, so don't make a connection
   7392                     // and just let the caller instantiate its own instance.
   7393                     ContentProviderHolder holder = cpr.newHolder(null);
   7394                     // don't give caller the provider object, it needs
   7395                     // to make its own.
   7396                     holder.provider = null;
   7397                     return holder;
   7398                 }
   7399 
   7400                 final long origId = Binder.clearCallingIdentity();
   7401 
   7402                 // In this case the provider instance already exists, so we can
   7403                 // return it right away.
   7404                 conn = incProviderCountLocked(r, cpr, token, stable);
   7405                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   7406                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   7407                         // If this is a perceptible app accessing the provider,
   7408                         // make sure to count it as being accessed and thus
   7409                         // back up on the LRU list.  This is good because
   7410                         // content providers are often expensive to start.
   7411                         updateLruProcessLocked(cpr.proc, false, false);
   7412                     }
   7413                 }
   7414 
   7415                 if (cpr.proc != null) {
   7416                     if (false) {
   7417                         if (cpr.name.flattenToShortString().equals(
   7418                                 "com.android.providers.calendar/.CalendarProvider2")) {
   7419                             Slog.v(TAG, "****************** KILLING "
   7420                                 + cpr.name.flattenToShortString());
   7421                             Process.killProcess(cpr.proc.pid);
   7422                         }
   7423                     }
   7424                     boolean success = updateOomAdjLocked(cpr.proc);
   7425                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   7426                     // NOTE: there is still a race here where a signal could be
   7427                     // pending on the process even though we managed to update its
   7428                     // adj level.  Not sure what to do about this, but at least
   7429                     // the race is now smaller.
   7430                     if (!success) {
   7431                         // Uh oh...  it looks like the provider's process
   7432                         // has been killed on us.  We need to wait for a new
   7433                         // process to be started, and make sure its death
   7434                         // doesn't kill our process.
   7435                         Slog.i(TAG,
   7436                                 "Existing provider " + cpr.name.flattenToShortString()
   7437                                 + " is crashing; detaching " + r);
   7438                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   7439                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   7440                         if (!lastRef) {
   7441                             // This wasn't the last ref our process had on
   7442                             // the provider...  we have now been killed, bail.
   7443                             return null;
   7444                         }
   7445                         providerRunning = false;
   7446                         conn = null;
   7447                     }
   7448                 }
   7449 
   7450                 Binder.restoreCallingIdentity(origId);
   7451             }
   7452 
   7453             boolean singleton;
   7454             if (!providerRunning) {
   7455                 try {
   7456                     cpi = AppGlobals.getPackageManager().
   7457                         resolveContentProvider(name,
   7458                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   7459                 } catch (RemoteException ex) {
   7460                 }
   7461                 if (cpi == null) {
   7462                     return null;
   7463                 }
   7464                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   7465                         cpi.name, cpi.flags);
   7466                 if (singleton) {
   7467                     userId = 0;
   7468                 }
   7469                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   7470 
   7471                 String msg;
   7472                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   7473                     throw new SecurityException(msg);
   7474                 }
   7475 
   7476                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   7477                         && !cpi.processName.equals("system")) {
   7478                     // If this content provider does not run in the system
   7479                     // process, and the system is not yet ready to run other
   7480                     // processes, then fail fast instead of hanging.
   7481                     throw new IllegalArgumentException(
   7482                             "Attempt to launch content provider before system ready");
   7483                 }
   7484 
   7485                 // Make sure that the user who owns this provider is started.  If not,
   7486                 // we don't want to allow it to run.
   7487                 if (mStartedUsers.get(userId) == null) {
   7488                     Slog.w(TAG, "Unable to launch app "
   7489                             + cpi.applicationInfo.packageName + "/"
   7490                             + cpi.applicationInfo.uid + " for provider "
   7491                             + name + ": user " + userId + " is stopped");
   7492                     return null;
   7493                 }
   7494 
   7495                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   7496                 cpr = mProviderMap.getProviderByClass(comp, userId);
   7497                 final boolean firstClass = cpr == null;
   7498                 if (firstClass) {
   7499                     try {
   7500                         ApplicationInfo ai =
   7501                             AppGlobals.getPackageManager().
   7502                                 getApplicationInfo(
   7503                                         cpi.applicationInfo.packageName,
   7504                                         STOCK_PM_FLAGS, userId);
   7505                         if (ai == null) {
   7506                             Slog.w(TAG, "No package info for content provider "
   7507                                     + cpi.name);
   7508                             return null;
   7509                         }
   7510                         ai = getAppInfoForUser(ai, userId);
   7511                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   7512                     } catch (RemoteException ex) {
   7513                         // pm is in same process, this will never happen.
   7514                     }
   7515                 }
   7516 
   7517                 if (r != null && cpr.canRunHere(r)) {
   7518                     // If this is a multiprocess provider, then just return its
   7519                     // info and allow the caller to instantiate it.  Only do
   7520                     // this if the provider is the same user as the caller's
   7521                     // process, or can run as root (so can be in any process).
   7522                     return cpr.newHolder(null);
   7523                 }
   7524 
   7525                 if (DEBUG_PROVIDER) {
   7526                     RuntimeException e = new RuntimeException("here");
   7527                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
   7528                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   7529                 }
   7530 
   7531                 // This is single process, and our app is now connecting to it.
   7532                 // See if we are already in the process of launching this
   7533                 // provider.
   7534                 final int N = mLaunchingProviders.size();
   7535                 int i;
   7536                 for (i=0; i<N; i++) {
   7537                     if (mLaunchingProviders.get(i) == cpr) {
   7538                         break;
   7539                     }
   7540                 }
   7541 
   7542                 // If the provider is not already being launched, then get it
   7543                 // started.
   7544                 if (i >= N) {
   7545                     final long origId = Binder.clearCallingIdentity();
   7546 
   7547                     try {
   7548                         // Content provider is now in use, its package can't be stopped.
   7549                         try {
   7550                             AppGlobals.getPackageManager().setPackageStoppedState(
   7551                                     cpr.appInfo.packageName, false, userId);
   7552                         } catch (RemoteException e) {
   7553                         } catch (IllegalArgumentException e) {
   7554                             Slog.w(TAG, "Failed trying to unstop package "
   7555                                     + cpr.appInfo.packageName + ": " + e);
   7556                         }
   7557 
   7558                         // Use existing process if already started
   7559                         ProcessRecord proc = getProcessRecordLocked(
   7560                                 cpi.processName, cpr.appInfo.uid, false);
   7561                         if (proc != null && proc.thread != null) {
   7562                             if (DEBUG_PROVIDER) {
   7563                                 Slog.d(TAG, "Installing in existing process " + proc);
   7564                             }
   7565                             proc.pubProviders.put(cpi.name, cpr);
   7566                             try {
   7567                                 proc.thread.scheduleInstallProvider(cpi);
   7568                             } catch (RemoteException e) {
   7569                             }
   7570                         } else {
   7571                             proc = startProcessLocked(cpi.processName,
   7572                                     cpr.appInfo, false, 0, "content provider",
   7573                                     new ComponentName(cpi.applicationInfo.packageName,
   7574                                             cpi.name), false, false, false);
   7575                             if (proc == null) {
   7576                                 Slog.w(TAG, "Unable to launch app "
   7577                                         + cpi.applicationInfo.packageName + "/"
   7578                                         + cpi.applicationInfo.uid + " for provider "
   7579                                         + name + ": process is bad");
   7580                                 return null;
   7581                             }
   7582                         }
   7583                         cpr.launchingApp = proc;
   7584                         mLaunchingProviders.add(cpr);
   7585                     } finally {
   7586                         Binder.restoreCallingIdentity(origId);
   7587                     }
   7588                 }
   7589 
   7590                 // Make sure the provider is published (the same provider class
   7591                 // may be published under multiple names).
   7592                 if (firstClass) {
   7593                     mProviderMap.putProviderByClass(comp, cpr);
   7594                 }
   7595 
   7596                 mProviderMap.putProviderByName(name, cpr);
   7597                 conn = incProviderCountLocked(r, cpr, token, stable);
   7598                 if (conn != null) {
   7599                     conn.waiting = true;
   7600                 }
   7601             }
   7602         }
   7603 
   7604         // Wait for the provider to be published...
   7605         synchronized (cpr) {
   7606             while (cpr.provider == null) {
   7607                 if (cpr.launchingApp == null) {
   7608                     Slog.w(TAG, "Unable to launch app "
   7609                             + cpi.applicationInfo.packageName + "/"
   7610                             + cpi.applicationInfo.uid + " for provider "
   7611                             + name + ": launching app became null");
   7612                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   7613                             UserHandle.getUserId(cpi.applicationInfo.uid),
   7614                             cpi.applicationInfo.packageName,
   7615                             cpi.applicationInfo.uid, name);
   7616                     return null;
   7617                 }
   7618                 try {
   7619                     if (DEBUG_MU) {
   7620                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   7621                                 + cpr.launchingApp);
   7622                     }
   7623                     if (conn != null) {
   7624                         conn.waiting = true;
   7625                     }
   7626                     cpr.wait();
   7627                 } catch (InterruptedException ex) {
   7628                 } finally {
   7629                     if (conn != null) {
   7630                         conn.waiting = false;
   7631                     }
   7632                 }
   7633             }
   7634         }
   7635         return cpr != null ? cpr.newHolder(conn) : null;
   7636     }
   7637 
   7638     public final ContentProviderHolder getContentProvider(
   7639             IApplicationThread caller, String name, int userId, boolean stable) {
   7640         enforceNotIsolatedCaller("getContentProvider");
   7641         if (caller == null) {
   7642             String msg = "null IApplicationThread when getting content provider "
   7643                     + name;
   7644             Slog.w(TAG, msg);
   7645             throw new SecurityException(msg);
   7646         }
   7647 
   7648         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   7649                 false, true, "getContentProvider", null);
   7650         return getContentProviderImpl(caller, name, null, stable, userId);
   7651     }
   7652 
   7653     public ContentProviderHolder getContentProviderExternal(
   7654             String name, int userId, IBinder token) {
   7655         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   7656             "Do not have permission in call getContentProviderExternal()");
   7657         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   7658                 false, true, "getContentProvider", null);
   7659         return getContentProviderExternalUnchecked(name, token, userId);
   7660     }
   7661 
   7662     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   7663             IBinder token, int userId) {
   7664         return getContentProviderImpl(null, name, token, true, userId);
   7665     }
   7666 
   7667     /**
   7668      * Drop a content provider from a ProcessRecord's bookkeeping
   7669      */
   7670     public void removeContentProvider(IBinder connection, boolean stable) {
   7671         enforceNotIsolatedCaller("removeContentProvider");
   7672         synchronized (this) {
   7673             ContentProviderConnection conn;
   7674             try {
   7675                 conn = (ContentProviderConnection)connection;
   7676             } catch (ClassCastException e) {
   7677                 String msg ="removeContentProvider: " + connection
   7678                         + " not a ContentProviderConnection";
   7679                 Slog.w(TAG, msg);
   7680                 throw new IllegalArgumentException(msg);
   7681             }
   7682             if (conn == null) {
   7683                 throw new NullPointerException("connection is null");
   7684             }
   7685             if (decProviderCountLocked(conn, null, null, stable)) {
   7686                 updateOomAdjLocked();
   7687             }
   7688         }
   7689     }
   7690 
   7691     public void removeContentProviderExternal(String name, IBinder token) {
   7692         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   7693             "Do not have permission in call removeContentProviderExternal()");
   7694         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
   7695     }
   7696 
   7697     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   7698         synchronized (this) {
   7699             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   7700             if(cpr == null) {
   7701                 //remove from mProvidersByClass
   7702                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   7703                 return;
   7704             }
   7705 
   7706             //update content provider record entry info
   7707             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   7708             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   7709             if (localCpr.hasExternalProcessHandles()) {
   7710                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   7711                     updateOomAdjLocked();
   7712                 } else {
   7713                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   7714                             + " with no external reference for token: "
   7715                             + token + ".");
   7716                 }
   7717             } else {
   7718                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   7719                         + " with no external references.");
   7720             }
   7721         }
   7722     }
   7723 
   7724     public final void publishContentProviders(IApplicationThread caller,
   7725             List<ContentProviderHolder> providers) {
   7726         if (providers == null) {
   7727             return;
   7728         }
   7729 
   7730         enforceNotIsolatedCaller("publishContentProviders");
   7731         synchronized (this) {
   7732             final ProcessRecord r = getRecordForAppLocked(caller);
   7733             if (DEBUG_MU)
   7734                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   7735             if (r == null) {
   7736                 throw new SecurityException(
   7737                         "Unable to find app for caller " + caller
   7738                       + " (pid=" + Binder.getCallingPid()
   7739                       + ") when publishing content providers");
   7740             }
   7741 
   7742             final long origId = Binder.clearCallingIdentity();
   7743 
   7744             final int N = providers.size();
   7745             for (int i=0; i<N; i++) {
   7746                 ContentProviderHolder src = providers.get(i);
   7747                 if (src == null || src.info == null || src.provider == null) {
   7748                     continue;
   7749                 }
   7750                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   7751                 if (DEBUG_MU)
   7752                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   7753                 if (dst != null) {
   7754                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   7755                     mProviderMap.putProviderByClass(comp, dst);
   7756                     String names[] = dst.info.authority.split(";");
   7757                     for (int j = 0; j < names.length; j++) {
   7758                         mProviderMap.putProviderByName(names[j], dst);
   7759                     }
   7760 
   7761                     int NL = mLaunchingProviders.size();
   7762                     int j;
   7763                     for (j=0; j<NL; j++) {
   7764                         if (mLaunchingProviders.get(j) == dst) {
   7765                             mLaunchingProviders.remove(j);
   7766                             j--;
   7767                             NL--;
   7768                         }
   7769                     }
   7770                     synchronized (dst) {
   7771                         dst.provider = src.provider;
   7772                         dst.proc = r;
   7773                         dst.notifyAll();
   7774                     }
   7775                     updateOomAdjLocked(r);
   7776                 }
   7777             }
   7778 
   7779             Binder.restoreCallingIdentity(origId);
   7780         }
   7781     }
   7782 
   7783     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   7784         ContentProviderConnection conn;
   7785         try {
   7786             conn = (ContentProviderConnection)connection;
   7787         } catch (ClassCastException e) {
   7788             String msg ="refContentProvider: " + connection
   7789                     + " not a ContentProviderConnection";
   7790             Slog.w(TAG, msg);
   7791             throw new IllegalArgumentException(msg);
   7792         }
   7793         if (conn == null) {
   7794             throw new NullPointerException("connection is null");
   7795         }
   7796 
   7797         synchronized (this) {
   7798             if (stable > 0) {
   7799                 conn.numStableIncs += stable;
   7800             }
   7801             stable = conn.stableCount + stable;
   7802             if (stable < 0) {
   7803                 throw new IllegalStateException("stableCount < 0: " + stable);
   7804             }
   7805 
   7806             if (unstable > 0) {
   7807                 conn.numUnstableIncs += unstable;
   7808             }
   7809             unstable = conn.unstableCount + unstable;
   7810             if (unstable < 0) {
   7811                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   7812             }
   7813 
   7814             if ((stable+unstable) <= 0) {
   7815                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   7816                         + stable + " unstable=" + unstable);
   7817             }
   7818             conn.stableCount = stable;
   7819             conn.unstableCount = unstable;
   7820             return !conn.dead;
   7821         }
   7822     }
   7823 
   7824     public void unstableProviderDied(IBinder connection) {
   7825         ContentProviderConnection conn;
   7826         try {
   7827             conn = (ContentProviderConnection)connection;
   7828         } catch (ClassCastException e) {
   7829             String msg ="refContentProvider: " + connection
   7830                     + " not a ContentProviderConnection";
   7831             Slog.w(TAG, msg);
   7832             throw new IllegalArgumentException(msg);
   7833         }
   7834         if (conn == null) {
   7835             throw new NullPointerException("connection is null");
   7836         }
   7837 
   7838         // Safely retrieve the content provider associated with the connection.
   7839         IContentProvider provider;
   7840         synchronized (this) {
   7841             provider = conn.provider.provider;
   7842         }
   7843 
   7844         if (provider == null) {
   7845             // Um, yeah, we're way ahead of you.
   7846             return;
   7847         }
   7848 
   7849         // Make sure the caller is being honest with us.
   7850         if (provider.asBinder().pingBinder()) {
   7851             // Er, no, still looks good to us.
   7852             synchronized (this) {
   7853                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   7854                         + " says " + conn + " died, but we don't agree");
   7855                 return;
   7856             }
   7857         }
   7858 
   7859         // Well look at that!  It's dead!
   7860         synchronized (this) {
   7861             if (conn.provider.provider != provider) {
   7862                 // But something changed...  good enough.
   7863                 return;
   7864             }
   7865 
   7866             ProcessRecord proc = conn.provider.proc;
   7867             if (proc == null || proc.thread == null) {
   7868                 // Seems like the process is already cleaned up.
   7869                 return;
   7870             }
   7871 
   7872             // As far as we're concerned, this is just like receiving a
   7873             // death notification...  just a bit prematurely.
   7874             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   7875                     + ") early provider death");
   7876             final long ident = Binder.clearCallingIdentity();
   7877             try {
   7878                 appDiedLocked(proc, proc.pid, proc.thread);
   7879             } finally {
   7880                 Binder.restoreCallingIdentity(ident);
   7881             }
   7882         }
   7883     }
   7884 
   7885     @Override
   7886     public void appNotRespondingViaProvider(IBinder connection) {
   7887         enforceCallingPermission(
   7888                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   7889 
   7890         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   7891         if (conn == null) {
   7892             Slog.w(TAG, "ContentProviderConnection is null");
   7893             return;
   7894         }
   7895 
   7896         final ProcessRecord host = conn.provider.proc;
   7897         if (host == null) {
   7898             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   7899             return;
   7900         }
   7901 
   7902         final long token = Binder.clearCallingIdentity();
   7903         try {
   7904             appNotResponding(host, null, null, false, "ContentProvider not responding");
   7905         } finally {
   7906             Binder.restoreCallingIdentity(token);
   7907         }
   7908     }
   7909 
   7910     public static final void installSystemProviders() {
   7911         List<ProviderInfo> providers;
   7912         synchronized (mSelf) {
   7913             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   7914             providers = mSelf.generateApplicationProvidersLocked(app);
   7915             if (providers != null) {
   7916                 for (int i=providers.size()-1; i>=0; i--) {
   7917                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   7918                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   7919                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   7920                                 + ": not system .apk");
   7921                         providers.remove(i);
   7922                     }
   7923                 }
   7924             }
   7925         }
   7926         if (providers != null) {
   7927             mSystemThread.installSystemProviders(providers);
   7928         }
   7929 
   7930         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   7931 
   7932         mSelf.mUsageStatsService.monitorPackages();
   7933     }
   7934 
   7935     /**
   7936      * Allows app to retrieve the MIME type of a URI without having permission
   7937      * to access its content provider.
   7938      *
   7939      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   7940      *
   7941      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   7942      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   7943      */
   7944     public String getProviderMimeType(Uri uri, int userId) {
   7945         enforceNotIsolatedCaller("getProviderMimeType");
   7946         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   7947                 userId, false, true, "getProviderMimeType", null);
   7948         final String name = uri.getAuthority();
   7949         final long ident = Binder.clearCallingIdentity();
   7950         ContentProviderHolder holder = null;
   7951 
   7952         try {
   7953             holder = getContentProviderExternalUnchecked(name, null, userId);
   7954             if (holder != null) {
   7955                 return holder.provider.getType(uri);
   7956             }
   7957         } catch (RemoteException e) {
   7958             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   7959             return null;
   7960         } finally {
   7961             if (holder != null) {
   7962                 removeContentProviderExternalUnchecked(name, null, userId);
   7963             }
   7964             Binder.restoreCallingIdentity(ident);
   7965         }
   7966 
   7967         return null;
   7968     }
   7969 
   7970     // =========================================================
   7971     // GLOBAL MANAGEMENT
   7972     // =========================================================
   7973 
   7974     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   7975             boolean isolated) {
   7976         String proc = customProcess != null ? customProcess : info.processName;
   7977         BatteryStatsImpl.Uid.Proc ps = null;
   7978         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   7979         int uid = info.uid;
   7980         if (isolated) {
   7981             int userId = UserHandle.getUserId(uid);
   7982             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   7983             while (true) {
   7984                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   7985                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   7986                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   7987                 }
   7988                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   7989                 mNextIsolatedProcessUid++;
   7990                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   7991                     // No process for this uid, use it.
   7992                     break;
   7993                 }
   7994                 stepsLeft--;
   7995                 if (stepsLeft <= 0) {
   7996                     return null;
   7997                 }
   7998             }
   7999         }
   8000         synchronized (stats) {
   8001             ps = stats.getProcessStatsLocked(info.uid, proc);
   8002         }
   8003         return new ProcessRecord(ps, info, proc, uid);
   8004     }
   8005 
   8006     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
   8007         ProcessRecord app;
   8008         if (!isolated) {
   8009             app = getProcessRecordLocked(info.processName, info.uid, true);
   8010         } else {
   8011             app = null;
   8012         }
   8013 
   8014         if (app == null) {
   8015             app = newProcessRecordLocked(info, null, isolated);
   8016             mProcessNames.put(info.processName, app.uid, app);
   8017             if (isolated) {
   8018                 mIsolatedProcesses.put(app.uid, app);
   8019             }
   8020             updateLruProcessLocked(app, true, false);
   8021         }
   8022 
   8023         // This package really, really can not be stopped.
   8024         try {
   8025             AppGlobals.getPackageManager().setPackageStoppedState(
   8026                     info.packageName, false, UserHandle.getUserId(app.uid));
   8027         } catch (RemoteException e) {
   8028         } catch (IllegalArgumentException e) {
   8029             Slog.w(TAG, "Failed trying to unstop package "
   8030                     + info.packageName + ": " + e);
   8031         }
   8032 
   8033         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   8034                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   8035             app.persistent = true;
   8036             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   8037         }
   8038         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   8039             mPersistentStartingProcesses.add(app);
   8040             startProcessLocked(app, "added application", app.processName);
   8041         }
   8042 
   8043         return app;
   8044     }
   8045 
   8046     public void unhandledBack() {
   8047         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   8048                 "unhandledBack()");
   8049 
   8050         synchronized(this) {
   8051             final long origId = Binder.clearCallingIdentity();
   8052             try {
   8053                 getFocusedStack().unhandledBackLocked();
   8054             } finally {
   8055                 Binder.restoreCallingIdentity(origId);
   8056             }
   8057         }
   8058     }
   8059 
   8060     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   8061         enforceNotIsolatedCaller("openContentUri");
   8062         final int userId = UserHandle.getCallingUserId();
   8063         String name = uri.getAuthority();
   8064         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   8065         ParcelFileDescriptor pfd = null;
   8066         if (cph != null) {
   8067             // We record the binder invoker's uid in thread-local storage before
   8068             // going to the content provider to open the file.  Later, in the code
   8069             // that handles all permissions checks, we look for this uid and use
   8070             // that rather than the Activity Manager's own uid.  The effect is that
   8071             // we do the check against the caller's permissions even though it looks
   8072             // to the content provider like the Activity Manager itself is making
   8073             // the request.
   8074             sCallerIdentity.set(new Identity(
   8075                     Binder.getCallingPid(), Binder.getCallingUid()));
   8076             try {
   8077                 pfd = cph.provider.openFile(null, uri, "r", null);
   8078             } catch (FileNotFoundException e) {
   8079                 // do nothing; pfd will be returned null
   8080             } finally {
   8081                 // Ensure that whatever happens, we clean up the identity state
   8082                 sCallerIdentity.remove();
   8083             }
   8084 
   8085             // We've got the fd now, so we're done with the provider.
   8086             removeContentProviderExternalUnchecked(name, null, userId);
   8087         } else {
   8088             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   8089         }
   8090         return pfd;
   8091     }
   8092 
   8093     // Actually is sleeping or shutting down or whatever else in the future
   8094     // is an inactive state.
   8095     public boolean isSleepingOrShuttingDown() {
   8096         return mSleeping || mShuttingDown;
   8097     }
   8098 
   8099     public void goingToSleep() {
   8100         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8101                 != PackageManager.PERMISSION_GRANTED) {
   8102             throw new SecurityException("Requires permission "
   8103                     + android.Manifest.permission.DEVICE_POWER);
   8104         }
   8105 
   8106         synchronized(this) {
   8107             mWentToSleep = true;
   8108             updateEventDispatchingLocked();
   8109 
   8110             if (!mSleeping) {
   8111                 mSleeping = true;
   8112                 mStackSupervisor.goingToSleepLocked();
   8113 
   8114                 // Initialize the wake times of all processes.
   8115                 checkExcessivePowerUsageLocked(false);
   8116                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   8117                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   8118                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   8119             }
   8120         }
   8121     }
   8122 
   8123     @Override
   8124     public boolean shutdown(int timeout) {
   8125         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   8126                 != PackageManager.PERMISSION_GRANTED) {
   8127             throw new SecurityException("Requires permission "
   8128                     + android.Manifest.permission.SHUTDOWN);
   8129         }
   8130 
   8131         boolean timedout = false;
   8132 
   8133         synchronized(this) {
   8134             mShuttingDown = true;
   8135             updateEventDispatchingLocked();
   8136             timedout = mStackSupervisor.shutdownLocked(timeout);
   8137         }
   8138 
   8139         mAppOpsService.shutdown();
   8140         mUsageStatsService.shutdown();
   8141         mBatteryStatsService.shutdown();
   8142         synchronized (this) {
   8143             mProcessStats.shutdownLocked();
   8144         }
   8145 
   8146         return timedout;
   8147     }
   8148 
   8149     public final void activitySlept(IBinder token) {
   8150         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
   8151 
   8152         final long origId = Binder.clearCallingIdentity();
   8153 
   8154         synchronized (this) {
   8155             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8156             if (r != null) {
   8157                 mStackSupervisor.activitySleptLocked(r);
   8158             }
   8159         }
   8160 
   8161         Binder.restoreCallingIdentity(origId);
   8162     }
   8163 
   8164     void logLockScreen(String msg) {
   8165         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
   8166                 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
   8167                 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
   8168                 mStackSupervisor.mDismissKeyguardOnNextActivity);
   8169     }
   8170 
   8171     private void comeOutOfSleepIfNeededLocked() {
   8172         if (!mWentToSleep && !mLockScreenShown) {
   8173             if (mSleeping) {
   8174                 mSleeping = false;
   8175                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
   8176             }
   8177         }
   8178     }
   8179 
   8180     public void wakingUp() {
   8181         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8182                 != PackageManager.PERMISSION_GRANTED) {
   8183             throw new SecurityException("Requires permission "
   8184                     + android.Manifest.permission.DEVICE_POWER);
   8185         }
   8186 
   8187         synchronized(this) {
   8188             mWentToSleep = false;
   8189             updateEventDispatchingLocked();
   8190             comeOutOfSleepIfNeededLocked();
   8191         }
   8192     }
   8193 
   8194     private void updateEventDispatchingLocked() {
   8195         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
   8196     }
   8197 
   8198     public void setLockScreenShown(boolean shown) {
   8199         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8200                 != PackageManager.PERMISSION_GRANTED) {
   8201             throw new SecurityException("Requires permission "
   8202                     + android.Manifest.permission.DEVICE_POWER);
   8203         }
   8204 
   8205         synchronized(this) {
   8206             long ident = Binder.clearCallingIdentity();
   8207             try {
   8208                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
   8209                 mLockScreenShown = shown;
   8210                 comeOutOfSleepIfNeededLocked();
   8211             } finally {
   8212                 Binder.restoreCallingIdentity(ident);
   8213             }
   8214         }
   8215     }
   8216 
   8217     public void stopAppSwitches() {
   8218         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8219                 != PackageManager.PERMISSION_GRANTED) {
   8220             throw new SecurityException("Requires permission "
   8221                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8222         }
   8223 
   8224         synchronized(this) {
   8225             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   8226                     + APP_SWITCH_DELAY_TIME;
   8227             mDidAppSwitch = false;
   8228             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8229             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8230             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   8231         }
   8232     }
   8233 
   8234     public void resumeAppSwitches() {
   8235         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8236                 != PackageManager.PERMISSION_GRANTED) {
   8237             throw new SecurityException("Requires permission "
   8238                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8239         }
   8240 
   8241         synchronized(this) {
   8242             // Note that we don't execute any pending app switches... we will
   8243             // let those wait until either the timeout, or the next start
   8244             // activity request.
   8245             mAppSwitchesAllowedTime = 0;
   8246         }
   8247     }
   8248 
   8249     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   8250             String name) {
   8251         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   8252             return true;
   8253         }
   8254 
   8255         final int perm = checkComponentPermission(
   8256                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   8257                 callingUid, -1, true);
   8258         if (perm == PackageManager.PERMISSION_GRANTED) {
   8259             return true;
   8260         }
   8261 
   8262         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   8263         return false;
   8264     }
   8265 
   8266     public void setDebugApp(String packageName, boolean waitForDebugger,
   8267             boolean persistent) {
   8268         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   8269                 "setDebugApp()");
   8270 
   8271         long ident = Binder.clearCallingIdentity();
   8272         try {
   8273             // Note that this is not really thread safe if there are multiple
   8274             // callers into it at the same time, but that's not a situation we
   8275             // care about.
   8276             if (persistent) {
   8277                 final ContentResolver resolver = mContext.getContentResolver();
   8278                 Settings.Global.putString(
   8279                     resolver, Settings.Global.DEBUG_APP,
   8280                     packageName);
   8281                 Settings.Global.putInt(
   8282                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   8283                     waitForDebugger ? 1 : 0);
   8284             }
   8285 
   8286             synchronized (this) {
   8287                 if (!persistent) {
   8288                     mOrigDebugApp = mDebugApp;
   8289                     mOrigWaitForDebugger = mWaitForDebugger;
   8290                 }
   8291                 mDebugApp = packageName;
   8292                 mWaitForDebugger = waitForDebugger;
   8293                 mDebugTransient = !persistent;
   8294                 if (packageName != null) {
   8295                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   8296                             UserHandle.USER_ALL, "set debug app");
   8297                 }
   8298             }
   8299         } finally {
   8300             Binder.restoreCallingIdentity(ident);
   8301         }
   8302     }
   8303 
   8304     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   8305         synchronized (this) {
   8306             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   8307             if (!isDebuggable) {
   8308                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   8309                     throw new SecurityException("Process not debuggable: " + app.packageName);
   8310                 }
   8311             }
   8312 
   8313             mOpenGlTraceApp = processName;
   8314         }
   8315     }
   8316 
   8317     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   8318             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   8319         synchronized (this) {
   8320             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   8321             if (!isDebuggable) {
   8322                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   8323                     throw new SecurityException("Process not debuggable: " + app.packageName);
   8324                 }
   8325             }
   8326             mProfileApp = processName;
   8327             mProfileFile = profileFile;
   8328             if (mProfileFd != null) {
   8329                 try {
   8330                     mProfileFd.close();
   8331                 } catch (IOException e) {
   8332                 }
   8333                 mProfileFd = null;
   8334             }
   8335             mProfileFd = profileFd;
   8336             mProfileType = 0;
   8337             mAutoStopProfiler = autoStopProfiler;
   8338         }
   8339     }
   8340 
   8341     @Override
   8342     public void setAlwaysFinish(boolean enabled) {
   8343         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   8344                 "setAlwaysFinish()");
   8345 
   8346         Settings.Global.putInt(
   8347                 mContext.getContentResolver(),
   8348                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   8349 
   8350         synchronized (this) {
   8351             mAlwaysFinishActivities = enabled;
   8352         }
   8353     }
   8354 
   8355     @Override
   8356     public void setActivityController(IActivityController controller) {
   8357         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   8358                 "setActivityController()");
   8359         synchronized (this) {
   8360             mController = controller;
   8361             Watchdog.getInstance().setActivityController(controller);
   8362         }
   8363     }
   8364 
   8365     @Override
   8366     public void setUserIsMonkey(boolean userIsMonkey) {
   8367         synchronized (this) {
   8368             synchronized (mPidsSelfLocked) {
   8369                 final int callingPid = Binder.getCallingPid();
   8370                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   8371                 if (precessRecord == null) {
   8372                     throw new SecurityException("Unknown process: " + callingPid);
   8373                 }
   8374                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   8375                     throw new SecurityException("Only an instrumentation process "
   8376                             + "with a UiAutomation can call setUserIsMonkey");
   8377                 }
   8378             }
   8379             mUserIsMonkey = userIsMonkey;
   8380         }
   8381     }
   8382 
   8383     @Override
   8384     public boolean isUserAMonkey() {
   8385         synchronized (this) {
   8386             // If there is a controller also implies the user is a monkey.
   8387             return (mUserIsMonkey || mController != null);
   8388         }
   8389     }
   8390 
   8391     public void requestBugReport() {
   8392         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   8393         SystemProperties.set("ctl.start", "bugreport");
   8394     }
   8395 
   8396     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   8397         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   8398     }
   8399 
   8400     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   8401         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   8402             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   8403         }
   8404         return KEY_DISPATCHING_TIMEOUT;
   8405     }
   8406 
   8407     @Override
   8408     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   8409         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   8410                 != PackageManager.PERMISSION_GRANTED) {
   8411             throw new SecurityException("Requires permission "
   8412                     + android.Manifest.permission.FILTER_EVENTS);
   8413         }
   8414         ProcessRecord proc;
   8415         long timeout;
   8416         synchronized (this) {
   8417             synchronized (mPidsSelfLocked) {
   8418                 proc = mPidsSelfLocked.get(pid);
   8419             }
   8420             timeout = getInputDispatchingTimeoutLocked(proc);
   8421         }
   8422 
   8423         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   8424             return -1;
   8425         }
   8426 
   8427         return timeout;
   8428     }
   8429 
   8430     /**
   8431      * Handle input dispatching timeouts.
   8432      * Returns whether input dispatching should be aborted or not.
   8433      */
   8434     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   8435             final ActivityRecord activity, final ActivityRecord parent,
   8436             final boolean aboveSystem, String reason) {
   8437         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   8438                 != PackageManager.PERMISSION_GRANTED) {
   8439             throw new SecurityException("Requires permission "
   8440                     + android.Manifest.permission.FILTER_EVENTS);
   8441         }
   8442 
   8443         final String annotation;
   8444         if (reason == null) {
   8445             annotation = "Input dispatching timed out";
   8446         } else {
   8447             annotation = "Input dispatching timed out (" + reason + ")";
   8448         }
   8449 
   8450         if (proc != null) {
   8451             synchronized (this) {
   8452                 if (proc.debugging) {
   8453                     return false;
   8454                 }
   8455 
   8456                 if (mDidDexOpt) {
   8457                     // Give more time since we were dexopting.
   8458                     mDidDexOpt = false;
   8459                     return false;
   8460                 }
   8461 
   8462                 if (proc.instrumentationClass != null) {
   8463                     Bundle info = new Bundle();
   8464                     info.putString("shortMsg", "keyDispatchingTimedOut");
   8465                     info.putString("longMsg", annotation);
   8466                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   8467                     return true;
   8468                 }
   8469             }
   8470             mHandler.post(new Runnable() {
   8471                 @Override
   8472                 public void run() {
   8473                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
   8474                 }
   8475             });
   8476         }
   8477 
   8478         return true;
   8479     }
   8480 
   8481     public Bundle getAssistContextExtras(int requestType) {
   8482         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   8483                 "getAssistContextExtras()");
   8484         PendingAssistExtras pae;
   8485         Bundle extras = new Bundle();
   8486         synchronized (this) {
   8487             ActivityRecord activity = getFocusedStack().mResumedActivity;
   8488             if (activity == null) {
   8489                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
   8490                 return null;
   8491             }
   8492             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   8493             if (activity.app == null || activity.app.thread == null) {
   8494                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   8495                 return extras;
   8496             }
   8497             if (activity.app.pid == Binder.getCallingPid()) {
   8498                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
   8499                 return extras;
   8500             }
   8501             pae = new PendingAssistExtras(activity);
   8502             try {
   8503                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   8504                         requestType);
   8505                 mPendingAssistExtras.add(pae);
   8506                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
   8507             } catch (RemoteException e) {
   8508                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   8509                 return extras;
   8510             }
   8511         }
   8512         synchronized (pae) {
   8513             while (!pae.haveResult) {
   8514                 try {
   8515                     pae.wait();
   8516                 } catch (InterruptedException e) {
   8517                 }
   8518             }
   8519             if (pae.result != null) {
   8520                 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   8521             }
   8522         }
   8523         synchronized (this) {
   8524             mPendingAssistExtras.remove(pae);
   8525             mHandler.removeCallbacks(pae);
   8526         }
   8527         return extras;
   8528     }
   8529 
   8530     public void reportAssistContextExtras(IBinder token, Bundle extras) {
   8531         PendingAssistExtras pae = (PendingAssistExtras)token;
   8532         synchronized (pae) {
   8533             pae.result = extras;
   8534             pae.haveResult = true;
   8535             pae.notifyAll();
   8536         }
   8537     }
   8538 
   8539     public void registerProcessObserver(IProcessObserver observer) {
   8540         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   8541                 "registerProcessObserver()");
   8542         synchronized (this) {
   8543             mProcessObservers.register(observer);
   8544         }
   8545     }
   8546 
   8547     @Override
   8548     public void unregisterProcessObserver(IProcessObserver observer) {
   8549         synchronized (this) {
   8550             mProcessObservers.unregister(observer);
   8551         }
   8552     }
   8553 
   8554     @Override
   8555     public boolean convertFromTranslucent(IBinder token) {
   8556         final long origId = Binder.clearCallingIdentity();
   8557         try {
   8558             synchronized (this) {
   8559                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8560                 if (r == null) {
   8561                     return false;
   8562                 }
   8563                 if (r.changeWindowTranslucency(true)) {
   8564                     mWindowManager.setAppFullscreen(token, true);
   8565                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   8566                     return true;
   8567                 }
   8568                 return false;
   8569             }
   8570         } finally {
   8571             Binder.restoreCallingIdentity(origId);
   8572         }
   8573     }
   8574 
   8575     @Override
   8576     public boolean convertToTranslucent(IBinder token) {
   8577         final long origId = Binder.clearCallingIdentity();
   8578         try {
   8579             synchronized (this) {
   8580                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8581                 if (r == null) {
   8582                     return false;
   8583                 }
   8584                 if (r.changeWindowTranslucency(false)) {
   8585                     r.task.stack.convertToTranslucent(r);
   8586                     mWindowManager.setAppFullscreen(token, false);
   8587                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   8588                     return true;
   8589                 }
   8590                 return false;
   8591             }
   8592         } finally {
   8593             Binder.restoreCallingIdentity(origId);
   8594         }
   8595     }
   8596 
   8597     @Override
   8598     public void setImmersive(IBinder token, boolean immersive) {
   8599         synchronized(this) {
   8600             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8601             if (r == null) {
   8602                 throw new IllegalArgumentException();
   8603             }
   8604             r.immersive = immersive;
   8605 
   8606             // update associated state if we're frontmost
   8607             if (r == mFocusedActivity) {
   8608                 if (DEBUG_IMMERSIVE) {
   8609                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   8610                 }
   8611                 applyUpdateLockStateLocked(r);
   8612             }
   8613         }
   8614     }
   8615 
   8616     @Override
   8617     public boolean isImmersive(IBinder token) {
   8618         synchronized (this) {
   8619             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8620             if (r == null) {
   8621                 throw new IllegalArgumentException();
   8622             }
   8623             return r.immersive;
   8624         }
   8625     }
   8626 
   8627     public boolean isTopActivityImmersive() {
   8628         enforceNotIsolatedCaller("startActivity");
   8629         synchronized (this) {
   8630             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
   8631             return (r != null) ? r.immersive : false;
   8632         }
   8633     }
   8634 
   8635     public final void enterSafeMode() {
   8636         synchronized(this) {
   8637             // It only makes sense to do this before the system is ready
   8638             // and started launching other packages.
   8639             if (!mSystemReady) {
   8640                 try {
   8641                     AppGlobals.getPackageManager().enterSafeMode();
   8642                 } catch (RemoteException e) {
   8643                 }
   8644             }
   8645         }
   8646     }
   8647 
   8648     public final void showSafeModeOverlay() {
   8649         View v = LayoutInflater.from(mContext).inflate(
   8650                 com.android.internal.R.layout.safe_mode, null);
   8651         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   8652         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   8653         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   8654         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   8655         lp.gravity = Gravity.BOTTOM | Gravity.START;
   8656         lp.format = v.getBackground().getOpacity();
   8657         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   8658                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   8659         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   8660         ((WindowManager)mContext.getSystemService(
   8661                 Context.WINDOW_SERVICE)).addView(v, lp);
   8662     }
   8663 
   8664     public void noteWakeupAlarm(IIntentSender sender) {
   8665         if (!(sender instanceof PendingIntentRecord)) {
   8666             return;
   8667         }
   8668         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8669         synchronized (stats) {
   8670             if (mBatteryStatsService.isOnBattery()) {
   8671                 mBatteryStatsService.enforceCallingPermission();
   8672                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   8673                 int MY_UID = Binder.getCallingUid();
   8674                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   8675                 BatteryStatsImpl.Uid.Pkg pkg =
   8676                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   8677                 pkg.incWakeupsLocked();
   8678             }
   8679         }
   8680     }
   8681 
   8682     public boolean killPids(int[] pids, String pReason, boolean secure) {
   8683         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8684             throw new SecurityException("killPids only available to the system");
   8685         }
   8686         String reason = (pReason == null) ? "Unknown" : pReason;
   8687         // XXX Note: don't acquire main activity lock here, because the window
   8688         // manager calls in with its locks held.
   8689 
   8690         boolean killed = false;
   8691         synchronized (mPidsSelfLocked) {
   8692             int[] types = new int[pids.length];
   8693             int worstType = 0;
   8694             for (int i=0; i<pids.length; i++) {
   8695                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8696                 if (proc != null) {
   8697                     int type = proc.setAdj;
   8698                     types[i] = type;
   8699                     if (type > worstType) {
   8700                         worstType = type;
   8701                     }
   8702                 }
   8703             }
   8704 
   8705             // If the worst oom_adj is somewhere in the cached proc LRU range,
   8706             // then constrain it so we will kill all cached procs.
   8707             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   8708                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   8709                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   8710             }
   8711 
   8712             // If this is not a secure call, don't let it kill processes that
   8713             // are important.
   8714             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   8715                 worstType = ProcessList.SERVICE_ADJ;
   8716             }
   8717 
   8718             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   8719             for (int i=0; i<pids.length; i++) {
   8720                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8721                 if (proc == null) {
   8722                     continue;
   8723                 }
   8724                 int adj = proc.setAdj;
   8725                 if (adj >= worstType && !proc.killedByAm) {
   8726                     killUnneededProcessLocked(proc, reason);
   8727                     killed = true;
   8728                 }
   8729             }
   8730         }
   8731         return killed;
   8732     }
   8733 
   8734     @Override
   8735     public void killUid(int uid, String reason) {
   8736         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8737             throw new SecurityException("killUid only available to the system");
   8738         }
   8739         synchronized (this) {
   8740             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   8741                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   8742                     reason != null ? reason : "kill uid");
   8743         }
   8744     }
   8745 
   8746     @Override
   8747     public boolean killProcessesBelowForeground(String reason) {
   8748         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8749             throw new SecurityException("killProcessesBelowForeground() only available to system");
   8750         }
   8751 
   8752         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   8753     }
   8754 
   8755     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   8756         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8757             throw new SecurityException("killProcessesBelowAdj() only available to system");
   8758         }
   8759 
   8760         boolean killed = false;
   8761         synchronized (mPidsSelfLocked) {
   8762             final int size = mPidsSelfLocked.size();
   8763             for (int i = 0; i < size; i++) {
   8764                 final int pid = mPidsSelfLocked.keyAt(i);
   8765                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   8766                 if (proc == null) continue;
   8767 
   8768                 final int adj = proc.setAdj;
   8769                 if (adj > belowAdj && !proc.killedByAm) {
   8770                     killUnneededProcessLocked(proc, reason);
   8771                     killed = true;
   8772                 }
   8773             }
   8774         }
   8775         return killed;
   8776     }
   8777 
   8778     @Override
   8779     public void hang(final IBinder who, boolean allowRestart) {
   8780         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   8781                 != PackageManager.PERMISSION_GRANTED) {
   8782             throw new SecurityException("Requires permission "
   8783                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   8784         }
   8785 
   8786         final IBinder.DeathRecipient death = new DeathRecipient() {
   8787             @Override
   8788             public void binderDied() {
   8789                 synchronized (this) {
   8790                     notifyAll();
   8791                 }
   8792             }
   8793         };
   8794 
   8795         try {
   8796             who.linkToDeath(death, 0);
   8797         } catch (RemoteException e) {
   8798             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   8799             return;
   8800         }
   8801 
   8802         synchronized (this) {
   8803             Watchdog.getInstance().setAllowRestart(allowRestart);
   8804             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   8805             synchronized (death) {
   8806                 while (who.isBinderAlive()) {
   8807                     try {
   8808                         death.wait();
   8809                     } catch (InterruptedException e) {
   8810                     }
   8811                 }
   8812             }
   8813             Watchdog.getInstance().setAllowRestart(true);
   8814         }
   8815     }
   8816 
   8817     @Override
   8818     public void restart() {
   8819         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   8820                 != PackageManager.PERMISSION_GRANTED) {
   8821             throw new SecurityException("Requires permission "
   8822                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   8823         }
   8824 
   8825         Log.i(TAG, "Sending shutdown broadcast...");
   8826 
   8827         BroadcastReceiver br = new BroadcastReceiver() {
   8828             @Override public void onReceive(Context context, Intent intent) {
   8829                 // Now the broadcast is done, finish up the low-level shutdown.
   8830                 Log.i(TAG, "Shutting down activity manager...");
   8831                 shutdown(10000);
   8832                 Log.i(TAG, "Shutdown complete, restarting!");
   8833                 Process.killProcess(Process.myPid());
   8834                 System.exit(10);
   8835             }
   8836         };
   8837 
   8838         // First send the high-level shut down broadcast.
   8839         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   8840         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   8841         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   8842         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   8843         mContext.sendOrderedBroadcastAsUser(intent,
   8844                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   8845         */
   8846         br.onReceive(mContext, intent);
   8847     }
   8848 
   8849     private long getLowRamTimeSinceIdle(long now) {
   8850         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   8851     }
   8852 
   8853     @Override
   8854     public void performIdleMaintenance() {
   8855         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   8856                 != PackageManager.PERMISSION_GRANTED) {
   8857             throw new SecurityException("Requires permission "
   8858                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   8859         }
   8860 
   8861         synchronized (this) {
   8862             final long now = SystemClock.uptimeMillis();
   8863             final long timeSinceLastIdle = now - mLastIdleTime;
   8864             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   8865             mLastIdleTime = now;
   8866             mLowRamTimeSinceLastIdle = 0;
   8867             if (mLowRamStartTime != 0) {
   8868                 mLowRamStartTime = now;
   8869             }
   8870 
   8871             StringBuilder sb = new StringBuilder(128);
   8872             sb.append("Idle maintenance over ");
   8873             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   8874             sb.append(" low RAM for ");
   8875             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   8876             Slog.i(TAG, sb.toString());
   8877 
   8878             // If at least 1/3 of our time since the last idle period has been spent
   8879             // with RAM low, then we want to kill processes.
   8880             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   8881 
   8882             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   8883                 ProcessRecord proc = mLruProcesses.get(i);
   8884                 if (proc.notCachedSinceIdle) {
   8885                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
   8886                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   8887                         if (doKilling && proc.initialIdlePss != 0
   8888                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   8889                             killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
   8890                                     + " from " + proc.initialIdlePss + ")");
   8891                         }
   8892                     }
   8893                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
   8894                     proc.notCachedSinceIdle = true;
   8895                     proc.initialIdlePss = 0;
   8896                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
   8897                             mSleeping, now);
   8898                 }
   8899             }
   8900 
   8901             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   8902             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   8903         }
   8904     }
   8905 
   8906     public final void startRunning(String pkg, String cls, String action,
   8907             String data) {
   8908         synchronized(this) {
   8909             if (mStartRunning) {
   8910                 return;
   8911             }
   8912             mStartRunning = true;
   8913             mTopComponent = pkg != null && cls != null
   8914                     ? new ComponentName(pkg, cls) : null;
   8915             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   8916             mTopData = data;
   8917             if (!mSystemReady) {
   8918                 return;
   8919             }
   8920         }
   8921 
   8922         systemReady(null);
   8923     }
   8924 
   8925     private void retrieveSettings() {
   8926         final ContentResolver resolver = mContext.getContentResolver();
   8927         String debugApp = Settings.Global.getString(
   8928             resolver, Settings.Global.DEBUG_APP);
   8929         boolean waitForDebugger = Settings.Global.getInt(
   8930             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   8931         boolean alwaysFinishActivities = Settings.Global.getInt(
   8932             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   8933         boolean forceRtl = Settings.Global.getInt(
   8934                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
   8935         // Transfer any global setting for forcing RTL layout, into a System Property
   8936         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   8937 
   8938         Configuration configuration = new Configuration();
   8939         Settings.System.getConfiguration(resolver, configuration);
   8940         if (forceRtl) {
   8941             // This will take care of setting the correct layout direction flags
   8942             configuration.setLayoutDirection(configuration.locale);
   8943         }
   8944 
   8945         synchronized (this) {
   8946             mDebugApp = mOrigDebugApp = debugApp;
   8947             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   8948             mAlwaysFinishActivities = alwaysFinishActivities;
   8949             // This happens before any activities are started, so we can
   8950             // change mConfiguration in-place.
   8951             updateConfigurationLocked(configuration, null, false, true);
   8952             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   8953         }
   8954     }
   8955 
   8956     public boolean testIsSystemReady() {
   8957         // no need to synchronize(this) just to read & return the value
   8958         return mSystemReady;
   8959     }
   8960 
   8961     private static File getCalledPreBootReceiversFile() {
   8962         File dataDir = Environment.getDataDirectory();
   8963         File systemDir = new File(dataDir, "system");
   8964         File fname = new File(systemDir, "called_pre_boots.dat");
   8965         return fname;
   8966     }
   8967 
   8968     static final int LAST_DONE_VERSION = 10000;
   8969 
   8970     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   8971         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   8972         File file = getCalledPreBootReceiversFile();
   8973         FileInputStream fis = null;
   8974         try {
   8975             fis = new FileInputStream(file);
   8976             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   8977             int fvers = dis.readInt();
   8978             if (fvers == LAST_DONE_VERSION) {
   8979                 String vers = dis.readUTF();
   8980                 String codename = dis.readUTF();
   8981                 String build = dis.readUTF();
   8982                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   8983                         && android.os.Build.VERSION.CODENAME.equals(codename)
   8984                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   8985                     int num = dis.readInt();
   8986                     while (num > 0) {
   8987                         num--;
   8988                         String pkg = dis.readUTF();
   8989                         String cls = dis.readUTF();
   8990                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   8991                     }
   8992                 }
   8993             }
   8994         } catch (FileNotFoundException e) {
   8995         } catch (IOException e) {
   8996             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   8997         } finally {
   8998             if (fis != null) {
   8999                 try {
   9000                     fis.close();
   9001                 } catch (IOException e) {
   9002                 }
   9003             }
   9004         }
   9005         return lastDoneReceivers;
   9006     }
   9007 
   9008     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   9009         File file = getCalledPreBootReceiversFile();
   9010         FileOutputStream fos = null;
   9011         DataOutputStream dos = null;
   9012         try {
   9013             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   9014             fos = new FileOutputStream(file);
   9015             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   9016             dos.writeInt(LAST_DONE_VERSION);
   9017             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   9018             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   9019             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   9020             dos.writeInt(list.size());
   9021             for (int i=0; i<list.size(); i++) {
   9022                 dos.writeUTF(list.get(i).getPackageName());
   9023                 dos.writeUTF(list.get(i).getClassName());
   9024             }
   9025         } catch (IOException e) {
   9026             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   9027             file.delete();
   9028         } finally {
   9029             FileUtils.sync(fos);
   9030             if (dos != null) {
   9031                 try {
   9032                     dos.close();
   9033                 } catch (IOException e) {
   9034                     // TODO Auto-generated catch block
   9035                     e.printStackTrace();
   9036                 }
   9037             }
   9038         }
   9039     }
   9040 
   9041     public void systemReady(final Runnable goingCallback) {
   9042         synchronized(this) {
   9043             if (mSystemReady) {
   9044                 if (goingCallback != null) goingCallback.run();
   9045                 return;
   9046             }
   9047 
   9048             // Check to see if there are any update receivers to run.
   9049             if (!mDidUpdate) {
   9050                 if (mWaitingUpdate) {
   9051                     return;
   9052                 }
   9053                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   9054                 List<ResolveInfo> ris = null;
   9055                 try {
   9056                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   9057                             intent, null, 0, 0);
   9058                 } catch (RemoteException e) {
   9059                 }
   9060                 if (ris != null) {
   9061                     for (int i=ris.size()-1; i>=0; i--) {
   9062                         if ((ris.get(i).activityInfo.applicationInfo.flags
   9063                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   9064                             ris.remove(i);
   9065                         }
   9066                     }
   9067                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   9068 
   9069                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   9070 
   9071                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   9072                     for (int i=0; i<ris.size(); i++) {
   9073                         ActivityInfo ai = ris.get(i).activityInfo;
   9074                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   9075                         if (lastDoneReceivers.contains(comp)) {
   9076                             ris.remove(i);
   9077                             i--;
   9078                         }
   9079                     }
   9080 
   9081                     final int[] users = getUsersLocked();
   9082                     for (int i=0; i<ris.size(); i++) {
   9083                         ActivityInfo ai = ris.get(i).activityInfo;
   9084                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   9085                         doneReceivers.add(comp);
   9086                         intent.setComponent(comp);
   9087                         for (int j=0; j<users.length; j++) {
   9088                             IIntentReceiver finisher = null;
   9089                             if (i == ris.size()-1 && j == users.length-1) {
   9090                                 finisher = new IIntentReceiver.Stub() {
   9091                                     public void performReceive(Intent intent, int resultCode,
   9092                                             String data, Bundle extras, boolean ordered,
   9093                                             boolean sticky, int sendingUser) {
   9094                                         // The raw IIntentReceiver interface is called
   9095                                         // with the AM lock held, so redispatch to
   9096                                         // execute our code without the lock.
   9097                                         mHandler.post(new Runnable() {
   9098                                             public void run() {
   9099                                                 synchronized (ActivityManagerService.this) {
   9100                                                     mDidUpdate = true;
   9101                                                 }
   9102                                                 writeLastDonePreBootReceivers(doneReceivers);
   9103                                                 showBootMessage(mContext.getText(
   9104                                                         R.string.android_upgrading_complete),
   9105                                                         false);
   9106                                                 systemReady(goingCallback);
   9107                                             }
   9108                                         });
   9109                                     }
   9110                                 };
   9111                             }
   9112                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
   9113                                     + " for user " + users[j]);
   9114                             broadcastIntentLocked(null, null, intent, null, finisher,
   9115                                     0, null, null, null, AppOpsManager.OP_NONE,
   9116                                     true, false, MY_PID, Process.SYSTEM_UID,
   9117                                     users[j]);
   9118                             if (finisher != null) {
   9119                                 mWaitingUpdate = true;
   9120                             }
   9121                         }
   9122                     }
   9123                 }
   9124                 if (mWaitingUpdate) {
   9125                     return;
   9126                 }
   9127                 mDidUpdate = true;
   9128             }
   9129 
   9130             mAppOpsService.systemReady();
   9131             mSystemReady = true;
   9132             if (!mStartRunning) {
   9133                 return;
   9134             }
   9135         }
   9136 
   9137         ArrayList<ProcessRecord> procsToKill = null;
   9138         synchronized(mPidsSelfLocked) {
   9139             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   9140                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   9141                 if (!isAllowedWhileBooting(proc.info)){
   9142                     if (procsToKill == null) {
   9143                         procsToKill = new ArrayList<ProcessRecord>();
   9144                     }
   9145                     procsToKill.add(proc);
   9146                 }
   9147             }
   9148         }
   9149 
   9150         synchronized(this) {
   9151             if (procsToKill != null) {
   9152                 for (int i=procsToKill.size()-1; i>=0; i--) {
   9153                     ProcessRecord proc = procsToKill.get(i);
   9154                     Slog.i(TAG, "Removing system update proc: " + proc);
   9155                     removeProcessLocked(proc, true, false, "system update done");
   9156                 }
   9157             }
   9158 
   9159             // Now that we have cleaned up any update processes, we
   9160             // are ready to start launching real processes and know that
   9161             // we won't trample on them any more.
   9162             mProcessesReady = true;
   9163         }
   9164 
   9165         Slog.i(TAG, "System now ready");
   9166         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   9167             SystemClock.uptimeMillis());
   9168 
   9169         synchronized(this) {
   9170             // Make sure we have no pre-ready processes sitting around.
   9171 
   9172             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9173                 ResolveInfo ri = mContext.getPackageManager()
   9174                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   9175                                 STOCK_PM_FLAGS);
   9176                 CharSequence errorMsg = null;
   9177                 if (ri != null) {
   9178                     ActivityInfo ai = ri.activityInfo;
   9179                     ApplicationInfo app = ai.applicationInfo;
   9180                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   9181                         mTopAction = Intent.ACTION_FACTORY_TEST;
   9182                         mTopData = null;
   9183                         mTopComponent = new ComponentName(app.packageName,
   9184                                 ai.name);
   9185                     } else {
   9186                         errorMsg = mContext.getResources().getText(
   9187                                 com.android.internal.R.string.factorytest_not_system);
   9188                     }
   9189                 } else {
   9190                     errorMsg = mContext.getResources().getText(
   9191                             com.android.internal.R.string.factorytest_no_action);
   9192                 }
   9193                 if (errorMsg != null) {
   9194                     mTopAction = null;
   9195                     mTopData = null;
   9196                     mTopComponent = null;
   9197                     Message msg = Message.obtain();
   9198                     msg.what = SHOW_FACTORY_ERROR_MSG;
   9199                     msg.getData().putCharSequence("msg", errorMsg);
   9200                     mHandler.sendMessage(msg);
   9201                 }
   9202             }
   9203         }
   9204 
   9205         retrieveSettings();
   9206 
   9207         synchronized (this) {
   9208             readGrantedUriPermissionsLocked();
   9209         }
   9210 
   9211         if (goingCallback != null) goingCallback.run();
   9212 
   9213         synchronized (this) {
   9214             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9215                 try {
   9216                     List apps = AppGlobals.getPackageManager().
   9217                         getPersistentApplications(STOCK_PM_FLAGS);
   9218                     if (apps != null) {
   9219                         int N = apps.size();
   9220                         int i;
   9221                         for (i=0; i<N; i++) {
   9222                             ApplicationInfo info
   9223                                 = (ApplicationInfo)apps.get(i);
   9224                             if (info != null &&
   9225                                     !info.packageName.equals("android")) {
   9226                                 addAppLocked(info, false);
   9227                             }
   9228                         }
   9229                     }
   9230                 } catch (RemoteException ex) {
   9231                     // pm is in same process, this will never happen.
   9232                 }
   9233             }
   9234 
   9235             // Start up initial activity.
   9236             mBooting = true;
   9237 
   9238             try {
   9239                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   9240                     Message msg = Message.obtain();
   9241                     msg.what = SHOW_UID_ERROR_MSG;
   9242                     mHandler.sendMessage(msg);
   9243                 }
   9244             } catch (RemoteException e) {
   9245             }
   9246 
   9247             long ident = Binder.clearCallingIdentity();
   9248             try {
   9249                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   9250                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   9251                         | Intent.FLAG_RECEIVER_FOREGROUND);
   9252                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9253                 broadcastIntentLocked(null, null, intent,
   9254                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   9255                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   9256                 intent = new Intent(Intent.ACTION_USER_STARTING);
   9257                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   9258                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9259                 broadcastIntentLocked(null, null, intent,
   9260                         null, new IIntentReceiver.Stub() {
   9261                             @Override
   9262                             public void performReceive(Intent intent, int resultCode, String data,
   9263                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   9264                                     throws RemoteException {
   9265                             }
   9266                         }, 0, null, null,
   9267                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   9268                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   9269             } finally {
   9270                 Binder.restoreCallingIdentity(ident);
   9271             }
   9272             mStackSupervisor.resumeTopActivitiesLocked();
   9273             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   9274         }
   9275     }
   9276 
   9277     private boolean makeAppCrashingLocked(ProcessRecord app,
   9278             String shortMsg, String longMsg, String stackTrace) {
   9279         app.crashing = true;
   9280         app.crashingReport = generateProcessError(app,
   9281                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   9282         startAppProblemLocked(app);
   9283         app.stopFreezingAllLocked();
   9284         return handleAppCrashLocked(app);
   9285     }
   9286 
   9287     private void makeAppNotRespondingLocked(ProcessRecord app,
   9288             String activity, String shortMsg, String longMsg) {
   9289         app.notResponding = true;
   9290         app.notRespondingReport = generateProcessError(app,
   9291                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   9292                 activity, shortMsg, longMsg, null);
   9293         startAppProblemLocked(app);
   9294         app.stopFreezingAllLocked();
   9295     }
   9296 
   9297     /**
   9298      * Generate a process error record, suitable for attachment to a ProcessRecord.
   9299      *
   9300      * @param app The ProcessRecord in which the error occurred.
   9301      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   9302      *                      ActivityManager.AppErrorStateInfo
   9303      * @param activity The activity associated with the crash, if known.
   9304      * @param shortMsg Short message describing the crash.
   9305      * @param longMsg Long message describing the crash.
   9306      * @param stackTrace Full crash stack trace, may be null.
   9307      *
   9308      * @return Returns a fully-formed AppErrorStateInfo record.
   9309      */
   9310     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   9311             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   9312         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   9313 
   9314         report.condition = condition;
   9315         report.processName = app.processName;
   9316         report.pid = app.pid;
   9317         report.uid = app.info.uid;
   9318         report.tag = activity;
   9319         report.shortMsg = shortMsg;
   9320         report.longMsg = longMsg;
   9321         report.stackTrace = stackTrace;
   9322 
   9323         return report;
   9324     }
   9325 
   9326     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   9327         synchronized (this) {
   9328             app.crashing = false;
   9329             app.crashingReport = null;
   9330             app.notResponding = false;
   9331             app.notRespondingReport = null;
   9332             if (app.anrDialog == fromDialog) {
   9333                 app.anrDialog = null;
   9334             }
   9335             if (app.waitDialog == fromDialog) {
   9336                 app.waitDialog = null;
   9337             }
   9338             if (app.pid > 0 && app.pid != MY_PID) {
   9339                 handleAppCrashLocked(app);
   9340                 killUnneededProcessLocked(app, "user request after error");
   9341             }
   9342         }
   9343     }
   9344 
   9345     private boolean handleAppCrashLocked(ProcessRecord app) {
   9346         if (mHeadless) {
   9347             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   9348             return false;
   9349         }
   9350         long now = SystemClock.uptimeMillis();
   9351 
   9352         Long crashTime;
   9353         if (!app.isolated) {
   9354             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   9355         } else {
   9356             crashTime = null;
   9357         }
   9358         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   9359             // This process loses!
   9360             Slog.w(TAG, "Process " + app.info.processName
   9361                     + " has crashed too many times: killing!");
   9362             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   9363                     app.userId, app.info.processName, app.uid);
   9364             mStackSupervisor.handleAppCrashLocked(app);
   9365             if (!app.persistent) {
   9366                 // We don't want to start this process again until the user
   9367                 // explicitly does so...  but for persistent process, we really
   9368                 // need to keep it running.  If a persistent process is actually
   9369                 // repeatedly crashing, then badness for everyone.
   9370                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   9371                         app.info.processName);
   9372                 if (!app.isolated) {
   9373                     // XXX We don't have a way to mark isolated processes
   9374                     // as bad, since they don't have a peristent identity.
   9375                     mBadProcesses.put(app.info.processName, app.uid, now);
   9376                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   9377                 }
   9378                 app.bad = true;
   9379                 app.removed = true;
   9380                 // Don't let services in this process be restarted and potentially
   9381                 // annoy the user repeatedly.  Unless it is persistent, since those
   9382                 // processes run critical code.
   9383                 removeProcessLocked(app, false, false, "crash");
   9384                 mStackSupervisor.resumeTopActivitiesLocked();
   9385                 return false;
   9386             }
   9387             mStackSupervisor.resumeTopActivitiesLocked();
   9388         } else {
   9389             mStackSupervisor.finishTopRunningActivityLocked(app);
   9390         }
   9391 
   9392         // Bump up the crash count of any services currently running in the proc.
   9393         for (int i=app.services.size()-1; i>=0; i--) {
   9394             // Any services running in the application need to be placed
   9395             // back in the pending list.
   9396             ServiceRecord sr = app.services.valueAt(i);
   9397             sr.crashCount++;
   9398         }
   9399 
   9400         // If the crashing process is what we consider to be the "home process" and it has been
   9401         // replaced by a third-party app, clear the package preferred activities from packages
   9402         // with a home activity running in the process to prevent a repeatedly crashing app
   9403         // from blocking the user to manually clear the list.
   9404         final ArrayList<ActivityRecord> activities = app.activities;
   9405         if (app == mHomeProcess && activities.size() > 0
   9406                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   9407             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   9408                 final ActivityRecord r = activities.get(activityNdx);
   9409                 if (r.isHomeActivity()) {
   9410                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   9411                     try {
   9412                         ActivityThread.getPackageManager()
   9413                                 .clearPackagePreferredActivities(r.packageName);
   9414                     } catch (RemoteException c) {
   9415                         // pm is in same process, this will never happen.
   9416                     }
   9417                 }
   9418             }
   9419         }
   9420 
   9421         if (!app.isolated) {
   9422             // XXX Can't keep track of crash times for isolated processes,
   9423             // because they don't have a perisistent identity.
   9424             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   9425         }
   9426 
   9427         return true;
   9428     }
   9429 
   9430     void startAppProblemLocked(ProcessRecord app) {
   9431         if (app.userId == mCurrentUserId) {
   9432             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   9433                     mContext, app.info.packageName, app.info.flags);
   9434         } else {
   9435             // If this app is not running under the current user, then we
   9436             // can't give it a report button because that would require
   9437             // launching the report UI under a different user.
   9438             app.errorReportReceiver = null;
   9439         }
   9440         skipCurrentReceiverLocked(app);
   9441     }
   9442 
   9443     void skipCurrentReceiverLocked(ProcessRecord app) {
   9444         for (BroadcastQueue queue : mBroadcastQueues) {
   9445             queue.skipCurrentReceiverLocked(app);
   9446         }
   9447     }
   9448 
   9449     /**
   9450      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   9451      * The application process will exit immediately after this call returns.
   9452      * @param app object of the crashing app, null for the system server
   9453      * @param crashInfo describing the exception
   9454      */
   9455     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   9456         ProcessRecord r = findAppProcess(app, "Crash");
   9457         final String processName = app == null ? "system_server"
   9458                 : (r == null ? "unknown" : r.processName);
   9459 
   9460         handleApplicationCrashInner("crash", r, processName, crashInfo);
   9461     }
   9462 
   9463     /* Native crash reporting uses this inner version because it needs to be somewhat
   9464      * decoupled from the AM-managed cleanup lifecycle
   9465      */
   9466     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   9467             ApplicationErrorReport.CrashInfo crashInfo) {
   9468         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   9469                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   9470                 r == null ? -1 : r.info.flags,
   9471                 crashInfo.exceptionClassName,
   9472                 crashInfo.exceptionMessage,
   9473                 crashInfo.throwFileName,
   9474                 crashInfo.throwLineNumber);
   9475 
   9476         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   9477 
   9478         crashApplication(r, crashInfo);
   9479     }
   9480 
   9481     public void handleApplicationStrictModeViolation(
   9482             IBinder app,
   9483             int violationMask,
   9484             StrictMode.ViolationInfo info) {
   9485         ProcessRecord r = findAppProcess(app, "StrictMode");
   9486         if (r == null) {
   9487             return;
   9488         }
   9489 
   9490         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   9491             Integer stackFingerprint = info.hashCode();
   9492             boolean logIt = true;
   9493             synchronized (mAlreadyLoggedViolatedStacks) {
   9494                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   9495                     logIt = false;
   9496                     // TODO: sub-sample into EventLog for these, with
   9497                     // the info.durationMillis?  Then we'd get
   9498                     // the relative pain numbers, without logging all
   9499                     // the stack traces repeatedly.  We'd want to do
   9500                     // likewise in the client code, which also does
   9501                     // dup suppression, before the Binder call.
   9502                 } else {
   9503                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   9504                         mAlreadyLoggedViolatedStacks.clear();
   9505                     }
   9506                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   9507                 }
   9508             }
   9509             if (logIt) {
   9510                 logStrictModeViolationToDropBox(r, info);
   9511             }
   9512         }
   9513 
   9514         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   9515             AppErrorResult result = new AppErrorResult();
   9516             synchronized (this) {
   9517                 final long origId = Binder.clearCallingIdentity();
   9518 
   9519                 Message msg = Message.obtain();
   9520                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   9521                 HashMap<String, Object> data = new HashMap<String, Object>();
   9522                 data.put("result", result);
   9523                 data.put("app", r);
   9524                 data.put("violationMask", violationMask);
   9525                 data.put("info", info);
   9526                 msg.obj = data;
   9527                 mHandler.sendMessage(msg);
   9528 
   9529                 Binder.restoreCallingIdentity(origId);
   9530             }
   9531             int res = result.get();
   9532             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   9533         }
   9534     }
   9535 
   9536     // Depending on the policy in effect, there could be a bunch of
   9537     // these in quick succession so we try to batch these together to
   9538     // minimize disk writes, number of dropbox entries, and maximize
   9539     // compression, by having more fewer, larger records.
   9540     private void logStrictModeViolationToDropBox(
   9541             ProcessRecord process,
   9542             StrictMode.ViolationInfo info) {
   9543         if (info == null) {
   9544             return;
   9545         }
   9546         final boolean isSystemApp = process == null ||
   9547                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   9548                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   9549         final String processName = process == null ? "unknown" : process.processName;
   9550         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   9551         final DropBoxManager dbox = (DropBoxManager)
   9552                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9553 
   9554         // Exit early if the dropbox isn't configured to accept this report type.
   9555         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9556 
   9557         boolean bufferWasEmpty;
   9558         boolean needsFlush;
   9559         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   9560         synchronized (sb) {
   9561             bufferWasEmpty = sb.length() == 0;
   9562             appendDropBoxProcessHeaders(process, processName, sb);
   9563             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9564             sb.append("System-App: ").append(isSystemApp).append("\n");
   9565             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   9566             if (info.violationNumThisLoop != 0) {
   9567                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   9568             }
   9569             if (info.numAnimationsRunning != 0) {
   9570                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   9571             }
   9572             if (info.broadcastIntentAction != null) {
   9573                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   9574             }
   9575             if (info.durationMillis != -1) {
   9576                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   9577             }
   9578             if (info.numInstances != -1) {
   9579                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   9580             }
   9581             if (info.tags != null) {
   9582                 for (String tag : info.tags) {
   9583                     sb.append("Span-Tag: ").append(tag).append("\n");
   9584                 }
   9585             }
   9586             sb.append("\n");
   9587             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   9588                 sb.append(info.crashInfo.stackTrace);
   9589             }
   9590             sb.append("\n");
   9591 
   9592             // Only buffer up to ~64k.  Various logging bits truncate
   9593             // things at 128k.
   9594             needsFlush = (sb.length() > 64 * 1024);
   9595         }
   9596 
   9597         // Flush immediately if the buffer's grown too large, or this
   9598         // is a non-system app.  Non-system apps are isolated with a
   9599         // different tag & policy and not batched.
   9600         //
   9601         // Batching is useful during internal testing with
   9602         // StrictMode settings turned up high.  Without batching,
   9603         // thousands of separate files could be created on boot.
   9604         if (!isSystemApp || needsFlush) {
   9605             new Thread("Error dump: " + dropboxTag) {
   9606                 @Override
   9607                 public void run() {
   9608                     String report;
   9609                     synchronized (sb) {
   9610                         report = sb.toString();
   9611                         sb.delete(0, sb.length());
   9612                         sb.trimToSize();
   9613                     }
   9614                     if (report.length() != 0) {
   9615                         dbox.addText(dropboxTag, report);
   9616                     }
   9617                 }
   9618             }.start();
   9619             return;
   9620         }
   9621 
   9622         // System app batching:
   9623         if (!bufferWasEmpty) {
   9624             // An existing dropbox-writing thread is outstanding, so
   9625             // we don't need to start it up.  The existing thread will
   9626             // catch the buffer appends we just did.
   9627             return;
   9628         }
   9629 
   9630         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   9631         // (After this point, we shouldn't access AMS internal data structures.)
   9632         new Thread("Error dump: " + dropboxTag) {
   9633             @Override
   9634             public void run() {
   9635                 // 5 second sleep to let stacks arrive and be batched together
   9636                 try {
   9637                     Thread.sleep(5000);  // 5 seconds
   9638                 } catch (InterruptedException e) {}
   9639 
   9640                 String errorReport;
   9641                 synchronized (mStrictModeBuffer) {
   9642                     errorReport = mStrictModeBuffer.toString();
   9643                     if (errorReport.length() == 0) {
   9644                         return;
   9645                     }
   9646                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   9647                     mStrictModeBuffer.trimToSize();
   9648                 }
   9649                 dbox.addText(dropboxTag, errorReport);
   9650             }
   9651         }.start();
   9652     }
   9653 
   9654     /**
   9655      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   9656      * @param app object of the crashing app, null for the system server
   9657      * @param tag reported by the caller
   9658      * @param crashInfo describing the context of the error
   9659      * @return true if the process should exit immediately (WTF is fatal)
   9660      */
   9661     public boolean handleApplicationWtf(IBinder app, String tag,
   9662             ApplicationErrorReport.CrashInfo crashInfo) {
   9663         ProcessRecord r = findAppProcess(app, "WTF");
   9664         final String processName = app == null ? "system_server"
   9665                 : (r == null ? "unknown" : r.processName);
   9666 
   9667         EventLog.writeEvent(EventLogTags.AM_WTF,
   9668                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
   9669                 processName,
   9670                 r == null ? -1 : r.info.flags,
   9671                 tag, crashInfo.exceptionMessage);
   9672 
   9673         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   9674 
   9675         if (r != null && r.pid != Process.myPid() &&
   9676                 Settings.Global.getInt(mContext.getContentResolver(),
   9677                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   9678             crashApplication(r, crashInfo);
   9679             return true;
   9680         } else {
   9681             return false;
   9682         }
   9683     }
   9684 
   9685     /**
   9686      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   9687      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   9688      */
   9689     private ProcessRecord findAppProcess(IBinder app, String reason) {
   9690         if (app == null) {
   9691             return null;
   9692         }
   9693 
   9694         synchronized (this) {
   9695             final int NP = mProcessNames.getMap().size();
   9696             for (int ip=0; ip<NP; ip++) {
   9697                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   9698                 final int NA = apps.size();
   9699                 for (int ia=0; ia<NA; ia++) {
   9700                     ProcessRecord p = apps.valueAt(ia);
   9701                     if (p.thread != null && p.thread.asBinder() == app) {
   9702                         return p;
   9703                     }
   9704                 }
   9705             }
   9706 
   9707             Slog.w(TAG, "Can't find mystery application for " + reason
   9708                     + " from pid=" + Binder.getCallingPid()
   9709                     + " uid=" + Binder.getCallingUid() + ": " + app);
   9710             return null;
   9711         }
   9712     }
   9713 
   9714     /**
   9715      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   9716      * to append various headers to the dropbox log text.
   9717      */
   9718     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   9719             StringBuilder sb) {
   9720         // Watchdog thread ends up invoking this function (with
   9721         // a null ProcessRecord) to add the stack file to dropbox.
   9722         // Do not acquire a lock on this (am) in such cases, as it
   9723         // could cause a potential deadlock, if and when watchdog
   9724         // is invoked due to unavailability of lock on am and it
   9725         // would prevent watchdog from killing system_server.
   9726         if (process == null) {
   9727             sb.append("Process: ").append(processName).append("\n");
   9728             return;
   9729         }
   9730         // Note: ProcessRecord 'process' is guarded by the service
   9731         // instance.  (notably process.pkgList, which could otherwise change
   9732         // concurrently during execution of this method)
   9733         synchronized (this) {
   9734             sb.append("Process: ").append(processName).append("\n");
   9735             int flags = process.info.flags;
   9736             IPackageManager pm = AppGlobals.getPackageManager();
   9737             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   9738             for (int ip=0; ip<process.pkgList.size(); ip++) {
   9739                 String pkg = process.pkgList.keyAt(ip);
   9740                 sb.append("Package: ").append(pkg);
   9741                 try {
   9742                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   9743                     if (pi != null) {
   9744                         sb.append(" v").append(pi.versionCode);
   9745                         if (pi.versionName != null) {
   9746                             sb.append(" (").append(pi.versionName).append(")");
   9747                         }
   9748                     }
   9749                 } catch (RemoteException e) {
   9750                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   9751                 }
   9752                 sb.append("\n");
   9753             }
   9754         }
   9755     }
   9756 
   9757     private static String processClass(ProcessRecord process) {
   9758         if (process == null || process.pid == MY_PID) {
   9759             return "system_server";
   9760         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   9761             return "system_app";
   9762         } else {
   9763             return "data_app";
   9764         }
   9765     }
   9766 
   9767     /**
   9768      * Write a description of an error (crash, WTF, ANR) to the drop box.
   9769      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   9770      * @param process which caused the error, null means the system server
   9771      * @param activity which triggered the error, null if unknown
   9772      * @param parent activity related to the error, null if unknown
   9773      * @param subject line related to the error, null if absent
   9774      * @param report in long form describing the error, null if absent
   9775      * @param logFile to include in the report, null if none
   9776      * @param crashInfo giving an application stack trace, null if absent
   9777      */
   9778     public void addErrorToDropBox(String eventType,
   9779             ProcessRecord process, String processName, ActivityRecord activity,
   9780             ActivityRecord parent, String subject,
   9781             final String report, final File logFile,
   9782             final ApplicationErrorReport.CrashInfo crashInfo) {
   9783         // NOTE -- this must never acquire the ActivityManagerService lock,
   9784         // otherwise the watchdog may be prevented from resetting the system.
   9785 
   9786         final String dropboxTag = processClass(process) + "_" + eventType;
   9787         final DropBoxManager dbox = (DropBoxManager)
   9788                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9789 
   9790         // Exit early if the dropbox isn't configured to accept this report type.
   9791         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9792 
   9793         final StringBuilder sb = new StringBuilder(1024);
   9794         appendDropBoxProcessHeaders(process, processName, sb);
   9795         if (activity != null) {
   9796             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   9797         }
   9798         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   9799             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   9800         }
   9801         if (parent != null && parent != activity) {
   9802             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   9803         }
   9804         if (subject != null) {
   9805             sb.append("Subject: ").append(subject).append("\n");
   9806         }
   9807         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9808         if (Debug.isDebuggerConnected()) {
   9809             sb.append("Debugger: Connected\n");
   9810         }
   9811         sb.append("\n");
   9812 
   9813         // Do the rest in a worker thread to avoid blocking the caller on I/O
   9814         // (After this point, we shouldn't access AMS internal data structures.)
   9815         Thread worker = new Thread("Error dump: " + dropboxTag) {
   9816             @Override
   9817             public void run() {
   9818                 if (report != null) {
   9819                     sb.append(report);
   9820                 }
   9821                 if (logFile != null) {
   9822                     try {
   9823                         sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
   9824                     } catch (IOException e) {
   9825                         Slog.e(TAG, "Error reading " + logFile, e);
   9826                     }
   9827                 }
   9828                 if (crashInfo != null && crashInfo.stackTrace != null) {
   9829                     sb.append(crashInfo.stackTrace);
   9830                 }
   9831 
   9832                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   9833                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   9834                 if (lines > 0) {
   9835                     sb.append("\n");
   9836 
   9837                     // Merge several logcat streams, and take the last N lines
   9838                     InputStreamReader input = null;
   9839                     try {
   9840                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   9841                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   9842                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   9843 
   9844                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   9845                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   9846                         input = new InputStreamReader(logcat.getInputStream());
   9847 
   9848                         int num;
   9849                         char[] buf = new char[8192];
   9850                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   9851                     } catch (IOException e) {
   9852                         Slog.e(TAG, "Error running logcat", e);
   9853                     } finally {
   9854                         if (input != null) try { input.close(); } catch (IOException e) {}
   9855                     }
   9856                 }
   9857 
   9858                 dbox.addText(dropboxTag, sb.toString());
   9859             }
   9860         };
   9861 
   9862         if (process == null) {
   9863             // If process is null, we are being called from some internal code
   9864             // and may be about to die -- run this synchronously.
   9865             worker.run();
   9866         } else {
   9867             worker.start();
   9868         }
   9869     }
   9870 
   9871     /**
   9872      * Bring up the "unexpected error" dialog box for a crashing app.
   9873      * Deal with edge cases (intercepts from instrumented applications,
   9874      * ActivityController, error intent receivers, that sort of thing).
   9875      * @param r the application crashing
   9876      * @param crashInfo describing the failure
   9877      */
   9878     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   9879         long timeMillis = System.currentTimeMillis();
   9880         String shortMsg = crashInfo.exceptionClassName;
   9881         String longMsg = crashInfo.exceptionMessage;
   9882         String stackTrace = crashInfo.stackTrace;
   9883         if (shortMsg != null && longMsg != null) {
   9884             longMsg = shortMsg + ": " + longMsg;
   9885         } else if (shortMsg != null) {
   9886             longMsg = shortMsg;
   9887         }
   9888 
   9889         AppErrorResult result = new AppErrorResult();
   9890         synchronized (this) {
   9891             if (mController != null) {
   9892                 try {
   9893                     String name = r != null ? r.processName : null;
   9894                     int pid = r != null ? r.pid : Binder.getCallingPid();
   9895                     if (!mController.appCrashed(name, pid,
   9896                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   9897                         Slog.w(TAG, "Force-killing crashed app " + name
   9898                                 + " at watcher's request");
   9899                         Process.killProcess(pid);
   9900                         return;
   9901                     }
   9902                 } catch (RemoteException e) {
   9903                     mController = null;
   9904                     Watchdog.getInstance().setActivityController(null);
   9905                 }
   9906             }
   9907 
   9908             final long origId = Binder.clearCallingIdentity();
   9909 
   9910             // If this process is running instrumentation, finish it.
   9911             if (r != null && r.instrumentationClass != null) {
   9912                 Slog.w(TAG, "Error in app " + r.processName
   9913                       + " running instrumentation " + r.instrumentationClass + ":");
   9914                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   9915                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   9916                 Bundle info = new Bundle();
   9917                 info.putString("shortMsg", shortMsg);
   9918                 info.putString("longMsg", longMsg);
   9919                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   9920                 Binder.restoreCallingIdentity(origId);
   9921                 return;
   9922             }
   9923 
   9924             // If we can't identify the process or it's already exceeded its crash quota,
   9925             // quit right away without showing a crash dialog.
   9926             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   9927                 Binder.restoreCallingIdentity(origId);
   9928                 return;
   9929             }
   9930 
   9931             Message msg = Message.obtain();
   9932             msg.what = SHOW_ERROR_MSG;
   9933             HashMap data = new HashMap();
   9934             data.put("result", result);
   9935             data.put("app", r);
   9936             msg.obj = data;
   9937             mHandler.sendMessage(msg);
   9938 
   9939             Binder.restoreCallingIdentity(origId);
   9940         }
   9941 
   9942         int res = result.get();
   9943 
   9944         Intent appErrorIntent = null;
   9945         synchronized (this) {
   9946             if (r != null && !r.isolated) {
   9947                 // XXX Can't keep track of crash time for isolated processes,
   9948                 // since they don't have a persistent identity.
   9949                 mProcessCrashTimes.put(r.info.processName, r.uid,
   9950                         SystemClock.uptimeMillis());
   9951             }
   9952             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   9953                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   9954             }
   9955         }
   9956 
   9957         if (appErrorIntent != null) {
   9958             try {
   9959                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   9960             } catch (ActivityNotFoundException e) {
   9961                 Slog.w(TAG, "bug report receiver dissappeared", e);
   9962             }
   9963         }
   9964     }
   9965 
   9966     Intent createAppErrorIntentLocked(ProcessRecord r,
   9967             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   9968         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   9969         if (report == null) {
   9970             return null;
   9971         }
   9972         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   9973         result.setComponent(r.errorReportReceiver);
   9974         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   9975         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   9976         return result;
   9977     }
   9978 
   9979     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   9980             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   9981         if (r.errorReportReceiver == null) {
   9982             return null;
   9983         }
   9984 
   9985         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   9986             return null;
   9987         }
   9988 
   9989         ApplicationErrorReport report = new ApplicationErrorReport();
   9990         report.packageName = r.info.packageName;
   9991         report.installerPackageName = r.errorReportReceiver.getPackageName();
   9992         report.processName = r.processName;
   9993         report.time = timeMillis;
   9994         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   9995 
   9996         if (r.crashing || r.forceCrashReport) {
   9997             report.type = ApplicationErrorReport.TYPE_CRASH;
   9998             report.crashInfo = crashInfo;
   9999         } else if (r.notResponding) {
   10000             report.type = ApplicationErrorReport.TYPE_ANR;
   10001             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   10002 
   10003             report.anrInfo.activity = r.notRespondingReport.tag;
   10004             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   10005             report.anrInfo.info = r.notRespondingReport.longMsg;
   10006         }
   10007 
   10008         return report;
   10009     }
   10010 
   10011     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   10012         enforceNotIsolatedCaller("getProcessesInErrorState");
   10013         // assume our apps are happy - lazy create the list
   10014         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   10015 
   10016         final boolean allUsers = ActivityManager.checkUidPermission(
   10017                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10018                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10019         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10020 
   10021         synchronized (this) {
   10022 
   10023             // iterate across all processes
   10024             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10025                 ProcessRecord app = mLruProcesses.get(i);
   10026                 if (!allUsers && app.userId != userId) {
   10027                     continue;
   10028                 }
   10029                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   10030                     // This one's in trouble, so we'll generate a report for it
   10031                     // crashes are higher priority (in case there's a crash *and* an anr)
   10032                     ActivityManager.ProcessErrorStateInfo report = null;
   10033                     if (app.crashing) {
   10034                         report = app.crashingReport;
   10035                     } else if (app.notResponding) {
   10036                         report = app.notRespondingReport;
   10037                     }
   10038 
   10039                     if (report != null) {
   10040                         if (errList == null) {
   10041                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   10042                         }
   10043                         errList.add(report);
   10044                     } else {
   10045                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   10046                                 " crashing = " + app.crashing +
   10047                                 " notResponding = " + app.notResponding);
   10048                     }
   10049                 }
   10050             }
   10051         }
   10052 
   10053         return errList;
   10054     }
   10055 
   10056     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   10057         if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   10058             if (currApp != null) {
   10059                 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
   10060             }
   10061             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10062         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   10063             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10064         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   10065             if (currApp != null) {
   10066                 currApp.lru = 0;
   10067             }
   10068             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10069         } else if (adj >= ProcessList.SERVICE_ADJ) {
   10070             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10071         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10072             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   10073         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10074             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   10075         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   10076             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   10077         } else {
   10078             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   10079         }
   10080     }
   10081 
   10082     private void fillInProcMemInfo(ProcessRecord app,
   10083             ActivityManager.RunningAppProcessInfo outInfo) {
   10084         outInfo.pid = app.pid;
   10085         outInfo.uid = app.info.uid;
   10086         if (mHeavyWeightProcess == app) {
   10087             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   10088         }
   10089         if (app.persistent) {
   10090             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   10091         }
   10092         if (app.hasActivities) {
   10093             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   10094         }
   10095         outInfo.lastTrimLevel = app.trimMemoryLevel;
   10096         int adj = app.curAdj;
   10097         outInfo.importance = oomAdjToImportance(adj, outInfo);
   10098         outInfo.importanceReasonCode = app.adjTypeCode;
   10099     }
   10100 
   10101     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   10102         enforceNotIsolatedCaller("getRunningAppProcesses");
   10103         // Lazy instantiation of list
   10104         List<ActivityManager.RunningAppProcessInfo> runList = null;
   10105         final boolean allUsers = ActivityManager.checkUidPermission(
   10106                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10107                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10108         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10109         synchronized (this) {
   10110             // Iterate across all processes
   10111             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10112                 ProcessRecord app = mLruProcesses.get(i);
   10113                 if (!allUsers && app.userId != userId) {
   10114                     continue;
   10115                 }
   10116                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   10117                     // Generate process state info for running application
   10118                     ActivityManager.RunningAppProcessInfo currApp =
   10119                         new ActivityManager.RunningAppProcessInfo(app.processName,
   10120                                 app.pid, app.getPackageList());
   10121                     fillInProcMemInfo(app, currApp);
   10122                     if (app.adjSource instanceof ProcessRecord) {
   10123                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   10124                         currApp.importanceReasonImportance = oomAdjToImportance(
   10125                                 app.adjSourceOom, null);
   10126                     } else if (app.adjSource instanceof ActivityRecord) {
   10127                         ActivityRecord r = (ActivityRecord)app.adjSource;
   10128                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   10129                     }
   10130                     if (app.adjTarget instanceof ComponentName) {
   10131                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   10132                     }
   10133                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   10134                     //        + " lru=" + currApp.lru);
   10135                     if (runList == null) {
   10136                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   10137                     }
   10138                     runList.add(currApp);
   10139                 }
   10140             }
   10141         }
   10142         return runList;
   10143     }
   10144 
   10145     public List<ApplicationInfo> getRunningExternalApplications() {
   10146         enforceNotIsolatedCaller("getRunningExternalApplications");
   10147         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   10148         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   10149         if (runningApps != null && runningApps.size() > 0) {
   10150             Set<String> extList = new HashSet<String>();
   10151             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   10152                 if (app.pkgList != null) {
   10153                     for (String pkg : app.pkgList) {
   10154                         extList.add(pkg);
   10155                     }
   10156                 }
   10157             }
   10158             IPackageManager pm = AppGlobals.getPackageManager();
   10159             for (String pkg : extList) {
   10160                 try {
   10161                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   10162                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   10163                         retList.add(info);
   10164                     }
   10165                 } catch (RemoteException e) {
   10166                 }
   10167             }
   10168         }
   10169         return retList;
   10170     }
   10171 
   10172     @Override
   10173     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   10174         enforceNotIsolatedCaller("getMyMemoryState");
   10175         synchronized (this) {
   10176             ProcessRecord proc;
   10177             synchronized (mPidsSelfLocked) {
   10178                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   10179             }
   10180             fillInProcMemInfo(proc, outInfo);
   10181         }
   10182     }
   10183 
   10184     @Override
   10185     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   10186         if (checkCallingPermission(android.Manifest.permission.DUMP)
   10187                 != PackageManager.PERMISSION_GRANTED) {
   10188             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   10189                     + Binder.getCallingPid()
   10190                     + ", uid=" + Binder.getCallingUid()
   10191                     + " without permission "
   10192                     + android.Manifest.permission.DUMP);
   10193             return;
   10194         }
   10195 
   10196         boolean dumpAll = false;
   10197         boolean dumpClient = false;
   10198         String dumpPackage = null;
   10199 
   10200         int opti = 0;
   10201         while (opti < args.length) {
   10202             String opt = args[opti];
   10203             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10204                 break;
   10205             }
   10206             opti++;
   10207             if ("-a".equals(opt)) {
   10208                 dumpAll = true;
   10209             } else if ("-c".equals(opt)) {
   10210                 dumpClient = true;
   10211             } else if ("-h".equals(opt)) {
   10212                 pw.println("Activity manager dump options:");
   10213                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   10214                 pw.println("  cmd may be one of:");
   10215                 pw.println("    a[ctivities]: activity stack state");
   10216                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   10217                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   10218                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   10219                 pw.println("    o[om]: out of memory management");
   10220                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   10221                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   10222                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   10223                 pw.println("    service [COMP_SPEC]: service client-side state");
   10224                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   10225                 pw.println("    all: dump all activities");
   10226                 pw.println("    top: dump the top activity");
   10227                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   10228                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   10229                 pw.println("    a partial substring in a component name, a");
   10230                 pw.println("    hex object identifier.");
   10231                 pw.println("  -a: include all available server state.");
   10232                 pw.println("  -c: include client state.");
   10233                 return;
   10234             } else {
   10235                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10236             }
   10237         }
   10238 
   10239         long origId = Binder.clearCallingIdentity();
   10240         boolean more = false;
   10241         // Is the caller requesting to dump a particular piece of data?
   10242         if (opti < args.length) {
   10243             String cmd = args[opti];
   10244             opti++;
   10245             if ("activities".equals(cmd) || "a".equals(cmd)) {
   10246                 synchronized (this) {
   10247                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   10248                 }
   10249             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   10250                 String[] newArgs;
   10251                 String name;
   10252                 if (opti >= args.length) {
   10253                     name = null;
   10254                     newArgs = EMPTY_STRING_ARRAY;
   10255                 } else {
   10256                     name = args[opti];
   10257                     opti++;
   10258                     newArgs = new String[args.length - opti];
   10259                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10260                             args.length - opti);
   10261                 }
   10262                 synchronized (this) {
   10263                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   10264                 }
   10265             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   10266                 String[] newArgs;
   10267                 String name;
   10268                 if (opti >= args.length) {
   10269                     name = null;
   10270                     newArgs = EMPTY_STRING_ARRAY;
   10271                 } else {
   10272                     name = args[opti];
   10273                     opti++;
   10274                     newArgs = new String[args.length - opti];
   10275                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10276                             args.length - opti);
   10277                 }
   10278                 synchronized (this) {
   10279                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   10280                 }
   10281             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   10282                 String[] newArgs;
   10283                 String name;
   10284                 if (opti >= args.length) {
   10285                     name = null;
   10286                     newArgs = EMPTY_STRING_ARRAY;
   10287                 } else {
   10288                     name = args[opti];
   10289                     opti++;
   10290                     newArgs = new String[args.length - opti];
   10291                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10292                             args.length - opti);
   10293                 }
   10294                 synchronized (this) {
   10295                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   10296                 }
   10297             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   10298                 synchronized (this) {
   10299                     dumpOomLocked(fd, pw, args, opti, true);
   10300                 }
   10301             } else if ("provider".equals(cmd)) {
   10302                 String[] newArgs;
   10303                 String name;
   10304                 if (opti >= args.length) {
   10305                     name = null;
   10306                     newArgs = EMPTY_STRING_ARRAY;
   10307                 } else {
   10308                     name = args[opti];
   10309                     opti++;
   10310                     newArgs = new String[args.length - opti];
   10311                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   10312                 }
   10313                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   10314                     pw.println("No providers match: " + name);
   10315                     pw.println("Use -h for help.");
   10316                 }
   10317             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   10318                 synchronized (this) {
   10319                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   10320                 }
   10321             } else if ("service".equals(cmd)) {
   10322                 String[] newArgs;
   10323                 String name;
   10324                 if (opti >= args.length) {
   10325                     name = null;
   10326                     newArgs = EMPTY_STRING_ARRAY;
   10327                 } else {
   10328                     name = args[opti];
   10329                     opti++;
   10330                     newArgs = new String[args.length - opti];
   10331                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10332                             args.length - opti);
   10333                 }
   10334                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   10335                     pw.println("No services match: " + name);
   10336                     pw.println("Use -h for help.");
   10337                 }
   10338             } else if ("package".equals(cmd)) {
   10339                 String[] newArgs;
   10340                 if (opti >= args.length) {
   10341                     pw.println("package: no package name specified");
   10342                     pw.println("Use -h for help.");
   10343                 } else {
   10344                     dumpPackage = args[opti];
   10345                     opti++;
   10346                     newArgs = new String[args.length - opti];
   10347                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10348                             args.length - opti);
   10349                     args = newArgs;
   10350                     opti = 0;
   10351                     more = true;
   10352                 }
   10353             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   10354                 synchronized (this) {
   10355                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   10356                 }
   10357             } else {
   10358                 // Dumping a single activity?
   10359                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   10360                     pw.println("Bad activity command, or no activities match: " + cmd);
   10361                     pw.println("Use -h for help.");
   10362                 }
   10363             }
   10364             if (!more) {
   10365                 Binder.restoreCallingIdentity(origId);
   10366                 return;
   10367             }
   10368         }
   10369 
   10370         // No piece of data specified, dump everything.
   10371         synchronized (this) {
   10372             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10373             pw.println();
   10374             if (dumpAll) {
   10375                 pw.println("-------------------------------------------------------------------------------");
   10376             }
   10377             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10378             pw.println();
   10379             if (dumpAll) {
   10380                 pw.println("-------------------------------------------------------------------------------");
   10381             }
   10382             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10383             pw.println();
   10384             if (dumpAll) {
   10385                 pw.println("-------------------------------------------------------------------------------");
   10386             }
   10387             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10388             pw.println();
   10389             if (dumpAll) {
   10390                 pw.println("-------------------------------------------------------------------------------");
   10391             }
   10392             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10393             pw.println();
   10394             if (dumpAll) {
   10395                 pw.println("-------------------------------------------------------------------------------");
   10396             }
   10397             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10398         }
   10399         Binder.restoreCallingIdentity(origId);
   10400     }
   10401 
   10402     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10403             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   10404         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   10405 
   10406         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   10407                 dumpPackage);
   10408         boolean needSep = printedAnything;
   10409 
   10410         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   10411                 dumpPackage, needSep, "  mFocusedActivity: ");
   10412         if (printed) {
   10413             printedAnything = true;
   10414             needSep = false;
   10415         }
   10416 
   10417         if (dumpPackage == null) {
   10418             if (needSep) {
   10419                 pw.println();
   10420             }
   10421             needSep = true;
   10422             printedAnything = true;
   10423             mStackSupervisor.dump(pw, "  ");
   10424         }
   10425 
   10426         if (mRecentTasks.size() > 0) {
   10427             boolean printedHeader = false;
   10428 
   10429             final int N = mRecentTasks.size();
   10430             for (int i=0; i<N; i++) {
   10431                 TaskRecord tr = mRecentTasks.get(i);
   10432                 if (dumpPackage != null) {
   10433                     if (tr.realActivity == null ||
   10434                             !dumpPackage.equals(tr.realActivity)) {
   10435                         continue;
   10436                     }
   10437                 }
   10438                 if (!printedHeader) {
   10439                     if (needSep) {
   10440                         pw.println();
   10441                     }
   10442                     pw.println("  Recent tasks:");
   10443                     printedHeader = true;
   10444                     printedAnything = true;
   10445                 }
   10446                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   10447                         pw.println(tr);
   10448                 if (dumpAll) {
   10449                     mRecentTasks.get(i).dump(pw, "    ");
   10450                 }
   10451             }
   10452         }
   10453 
   10454         if (!printedAnything) {
   10455             pw.println("  (nothing)");
   10456         }
   10457     }
   10458 
   10459     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10460             int opti, boolean dumpAll, String dumpPackage) {
   10461         boolean needSep = false;
   10462         boolean printedAnything = false;
   10463         int numPers = 0;
   10464 
   10465         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   10466 
   10467         if (dumpAll) {
   10468             final int NP = mProcessNames.getMap().size();
   10469             for (int ip=0; ip<NP; ip++) {
   10470                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   10471                 final int NA = procs.size();
   10472                 for (int ia=0; ia<NA; ia++) {
   10473                     ProcessRecord r = procs.valueAt(ia);
   10474                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10475                         continue;
   10476                     }
   10477                     if (!needSep) {
   10478                         pw.println("  All known processes:");
   10479                         needSep = true;
   10480                         printedAnything = true;
   10481                     }
   10482                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   10483                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   10484                         pw.print(" "); pw.println(r);
   10485                     r.dump(pw, "    ");
   10486                     if (r.persistent) {
   10487                         numPers++;
   10488                     }
   10489                 }
   10490             }
   10491         }
   10492 
   10493         if (mIsolatedProcesses.size() > 0) {
   10494             boolean printed = false;
   10495             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   10496                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   10497                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10498                     continue;
   10499                 }
   10500                 if (!printed) {
   10501                     if (needSep) {
   10502                         pw.println();
   10503                     }
   10504                     pw.println("  Isolated process list (sorted by uid):");
   10505                     printedAnything = true;
   10506                     printed = true;
   10507                     needSep = true;
   10508                 }
   10509                 pw.println(String.format("%sIsolated #%2d: %s",
   10510                         "    ", i, r.toString()));
   10511             }
   10512         }
   10513 
   10514         if (mLruProcesses.size() > 0) {
   10515             if (needSep) {
   10516                 pw.println();
   10517             }
   10518             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   10519                     pw.print(" total, non-act at ");
   10520                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   10521                     pw.print(", non-svc at ");
   10522                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   10523                     pw.println("):");
   10524             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   10525             needSep = true;
   10526             printedAnything = true;
   10527         }
   10528 
   10529         if (dumpAll || dumpPackage != null) {
   10530             synchronized (mPidsSelfLocked) {
   10531                 boolean printed = false;
   10532                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   10533                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   10534                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10535                         continue;
   10536                     }
   10537                     if (!printed) {
   10538                         if (needSep) pw.println();
   10539                         needSep = true;
   10540                         pw.println("  PID mappings:");
   10541                         printed = true;
   10542                         printedAnything = true;
   10543                     }
   10544                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   10545                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   10546                 }
   10547             }
   10548         }
   10549 
   10550         if (mForegroundProcesses.size() > 0) {
   10551             synchronized (mPidsSelfLocked) {
   10552                 boolean printed = false;
   10553                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   10554                     ProcessRecord r = mPidsSelfLocked.get(
   10555                             mForegroundProcesses.valueAt(i).pid);
   10556                     if (dumpPackage != null && (r == null
   10557                             || !r.pkgList.containsKey(dumpPackage))) {
   10558                         continue;
   10559                     }
   10560                     if (!printed) {
   10561                         if (needSep) pw.println();
   10562                         needSep = true;
   10563                         pw.println("  Foreground Processes:");
   10564                         printed = true;
   10565                         printedAnything = true;
   10566                     }
   10567                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   10568                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   10569                 }
   10570             }
   10571         }
   10572 
   10573         if (mPersistentStartingProcesses.size() > 0) {
   10574             if (needSep) pw.println();
   10575             needSep = true;
   10576             printedAnything = true;
   10577             pw.println("  Persisent processes that are starting:");
   10578             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   10579                     "Starting Norm", "Restarting PERS", dumpPackage);
   10580         }
   10581 
   10582         if (mRemovedProcesses.size() > 0) {
   10583             if (needSep) pw.println();
   10584             needSep = true;
   10585             printedAnything = true;
   10586             pw.println("  Processes that are being removed:");
   10587             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   10588                     "Removed Norm", "Removed PERS", dumpPackage);
   10589         }
   10590 
   10591         if (mProcessesOnHold.size() > 0) {
   10592             if (needSep) pw.println();
   10593             needSep = true;
   10594             printedAnything = true;
   10595             pw.println("  Processes that are on old until the system is ready:");
   10596             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   10597                     "OnHold Norm", "OnHold PERS", dumpPackage);
   10598         }
   10599 
   10600         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   10601 
   10602         if (mProcessCrashTimes.getMap().size() > 0) {
   10603             boolean printed = false;
   10604             long now = SystemClock.uptimeMillis();
   10605             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   10606             final int NP = pmap.size();
   10607             for (int ip=0; ip<NP; ip++) {
   10608                 String pname = pmap.keyAt(ip);
   10609                 SparseArray<Long> uids = pmap.valueAt(ip);
   10610                 final int N = uids.size();
   10611                 for (int i=0; i<N; i++) {
   10612                     int puid = uids.keyAt(i);
   10613                     ProcessRecord r = mProcessNames.get(pname, puid);
   10614                     if (dumpPackage != null && (r == null
   10615                             || !r.pkgList.containsKey(dumpPackage))) {
   10616                         continue;
   10617                     }
   10618                     if (!printed) {
   10619                         if (needSep) pw.println();
   10620                         needSep = true;
   10621                         pw.println("  Time since processes crashed:");
   10622                         printed = true;
   10623                         printedAnything = true;
   10624                     }
   10625                     pw.print("    Process "); pw.print(pname);
   10626                             pw.print(" uid "); pw.print(puid);
   10627                             pw.print(": last crashed ");
   10628                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   10629                             pw.println(" ago");
   10630                 }
   10631             }
   10632         }
   10633 
   10634         if (mBadProcesses.getMap().size() > 0) {
   10635             boolean printed = false;
   10636             final ArrayMap<String, SparseArray<Long>> pmap = mBadProcesses.getMap();
   10637             final int NP = pmap.size();
   10638             for (int ip=0; ip<NP; ip++) {
   10639                 String pname = pmap.keyAt(ip);
   10640                 SparseArray<Long> uids = pmap.valueAt(ip);
   10641                 final int N = uids.size();
   10642                 for (int i=0; i<N; i++) {
   10643                     int puid = uids.keyAt(i);
   10644                     ProcessRecord r = mProcessNames.get(pname, puid);
   10645                     if (dumpPackage != null && (r == null
   10646                             || !r.pkgList.containsKey(dumpPackage))) {
   10647                         continue;
   10648                     }
   10649                     if (!printed) {
   10650                         if (needSep) pw.println();
   10651                         needSep = true;
   10652                         pw.println("  Bad processes:");
   10653                         printedAnything = true;
   10654                     }
   10655                     pw.print("    Bad process "); pw.print(pname);
   10656                             pw.print(" uid "); pw.print(puid);
   10657                             pw.print(": crashed at time ");
   10658                             pw.println(uids.valueAt(i));
   10659                 }
   10660             }
   10661         }
   10662 
   10663         if (dumpPackage == null) {
   10664             pw.println();
   10665             needSep = false;
   10666             pw.println("  mStartedUsers:");
   10667             for (int i=0; i<mStartedUsers.size(); i++) {
   10668                 UserStartedState uss = mStartedUsers.valueAt(i);
   10669                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   10670                         pw.print(": "); uss.dump("", pw);
   10671             }
   10672             pw.print("  mStartedUserArray: [");
   10673             for (int i=0; i<mStartedUserArray.length; i++) {
   10674                 if (i > 0) pw.print(", ");
   10675                 pw.print(mStartedUserArray[i]);
   10676             }
   10677             pw.println("]");
   10678             pw.print("  mUserLru: [");
   10679             for (int i=0; i<mUserLru.size(); i++) {
   10680                 if (i > 0) pw.print(", ");
   10681                 pw.print(mUserLru.get(i));
   10682             }
   10683             pw.println("]");
   10684             if (dumpAll) {
   10685                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   10686             }
   10687         }
   10688         if (mHomeProcess != null && (dumpPackage == null
   10689                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   10690             if (needSep) {
   10691                 pw.println();
   10692                 needSep = false;
   10693             }
   10694             pw.println("  mHomeProcess: " + mHomeProcess);
   10695         }
   10696         if (mPreviousProcess != null && (dumpPackage == null
   10697                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   10698             if (needSep) {
   10699                 pw.println();
   10700                 needSep = false;
   10701             }
   10702             pw.println("  mPreviousProcess: " + mPreviousProcess);
   10703         }
   10704         if (dumpAll) {
   10705             StringBuilder sb = new StringBuilder(128);
   10706             sb.append("  mPreviousProcessVisibleTime: ");
   10707             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   10708             pw.println(sb);
   10709         }
   10710         if (mHeavyWeightProcess != null && (dumpPackage == null
   10711                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   10712             if (needSep) {
   10713                 pw.println();
   10714                 needSep = false;
   10715             }
   10716             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   10717         }
   10718         if (dumpPackage == null) {
   10719             pw.println("  mConfiguration: " + mConfiguration);
   10720         }
   10721         if (dumpAll) {
   10722             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   10723             if (mCompatModePackages.getPackages().size() > 0) {
   10724                 boolean printed = false;
   10725                 for (Map.Entry<String, Integer> entry
   10726                         : mCompatModePackages.getPackages().entrySet()) {
   10727                     String pkg = entry.getKey();
   10728                     int mode = entry.getValue();
   10729                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   10730                         continue;
   10731                     }
   10732                     if (!printed) {
   10733                         pw.println("  mScreenCompatPackages:");
   10734                         printed = true;
   10735                     }
   10736                     pw.print("    "); pw.print(pkg); pw.print(": ");
   10737                             pw.print(mode); pw.println();
   10738                 }
   10739             }
   10740         }
   10741         if (dumpPackage == null) {
   10742             if (mSleeping || mWentToSleep || mLockScreenShown) {
   10743                 pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   10744                         + " mLockScreenShown " + mLockScreenShown);
   10745             }
   10746             if (mShuttingDown) {
   10747                 pw.println("  mShuttingDown=" + mShuttingDown);
   10748             }
   10749         }
   10750         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   10751                 || mOrigWaitForDebugger) {
   10752             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   10753                     || dumpPackage.equals(mOrigDebugApp)) {
   10754                 if (needSep) {
   10755                     pw.println();
   10756                     needSep = false;
   10757                 }
   10758                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   10759                         + " mDebugTransient=" + mDebugTransient
   10760                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   10761             }
   10762         }
   10763         if (mOpenGlTraceApp != null) {
   10764             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   10765                 if (needSep) {
   10766                     pw.println();
   10767                     needSep = false;
   10768                 }
   10769                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   10770             }
   10771         }
   10772         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   10773                 || mProfileFd != null) {
   10774             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   10775                 if (needSep) {
   10776                     pw.println();
   10777                     needSep = false;
   10778                 }
   10779                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   10780                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   10781                 pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   10782                         + mAutoStopProfiler);
   10783             }
   10784         }
   10785         if (dumpPackage == null) {
   10786             if (mAlwaysFinishActivities || mController != null) {
   10787                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   10788                         + " mController=" + mController);
   10789             }
   10790             if (dumpAll) {
   10791                 pw.println("  Total persistent processes: " + numPers);
   10792                 pw.println("  mStartRunning=" + mStartRunning
   10793                         + " mProcessesReady=" + mProcessesReady
   10794                         + " mSystemReady=" + mSystemReady);
   10795                 pw.println("  mBooting=" + mBooting
   10796                         + " mBooted=" + mBooted
   10797                         + " mFactoryTest=" + mFactoryTest);
   10798                 pw.print("  mLastPowerCheckRealtime=");
   10799                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   10800                         pw.println("");
   10801                 pw.print("  mLastPowerCheckUptime=");
   10802                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   10803                         pw.println("");
   10804                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   10805                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   10806                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   10807                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   10808                         + " (" + mLruProcesses.size() + " total)"
   10809                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   10810                         + " mNumServiceProcs=" + mNumServiceProcs
   10811                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   10812                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   10813                         + " mLastMemoryLevel" + mLastMemoryLevel
   10814                         + " mLastNumProcesses" + mLastNumProcesses);
   10815                 long now = SystemClock.uptimeMillis();
   10816                 pw.print("  mLastIdleTime=");
   10817                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   10818                         pw.print(" mLowRamSinceLastIdle=");
   10819                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   10820                         pw.println();
   10821             }
   10822         }
   10823 
   10824         if (!printedAnything) {
   10825             pw.println("  (nothing)");
   10826         }
   10827     }
   10828 
   10829     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   10830             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   10831         if (mProcessesToGc.size() > 0) {
   10832             boolean printed = false;
   10833             long now = SystemClock.uptimeMillis();
   10834             for (int i=0; i<mProcessesToGc.size(); i++) {
   10835                 ProcessRecord proc = mProcessesToGc.get(i);
   10836                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   10837                     continue;
   10838                 }
   10839                 if (!printed) {
   10840                     if (needSep) pw.println();
   10841                     needSep = true;
   10842                     pw.println("  Processes that are waiting to GC:");
   10843                     printed = true;
   10844                 }
   10845                 pw.print("    Process "); pw.println(proc);
   10846                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   10847                         pw.print(", last gced=");
   10848                         pw.print(now-proc.lastRequestedGc);
   10849                         pw.print(" ms ago, last lowMem=");
   10850                         pw.print(now-proc.lastLowMemory);
   10851                         pw.println(" ms ago");
   10852 
   10853             }
   10854         }
   10855         return needSep;
   10856     }
   10857 
   10858     void printOomLevel(PrintWriter pw, String name, int adj) {
   10859         pw.print("    ");
   10860         if (adj >= 0) {
   10861             pw.print(' ');
   10862             if (adj < 10) pw.print(' ');
   10863         } else {
   10864             if (adj > -10) pw.print(' ');
   10865         }
   10866         pw.print(adj);
   10867         pw.print(": ");
   10868         pw.print(name);
   10869         pw.print(" (");
   10870         pw.print(mProcessList.getMemLevel(adj)/1024);
   10871         pw.println(" kB)");
   10872     }
   10873 
   10874     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10875             int opti, boolean dumpAll) {
   10876         boolean needSep = false;
   10877 
   10878         if (mLruProcesses.size() > 0) {
   10879             if (needSep) pw.println();
   10880             needSep = true;
   10881             pw.println("  OOM levels:");
   10882             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   10883             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   10884             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   10885             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   10886             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   10887             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   10888             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   10889             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   10890             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   10891             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   10892             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   10893             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   10894             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   10895 
   10896             if (needSep) pw.println();
   10897             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   10898                     pw.print(" total, non-act at ");
   10899                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   10900                     pw.print(", non-svc at ");
   10901                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   10902                     pw.println("):");
   10903             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   10904             needSep = true;
   10905         }
   10906 
   10907         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   10908 
   10909         pw.println();
   10910         pw.println("  mHomeProcess: " + mHomeProcess);
   10911         pw.println("  mPreviousProcess: " + mPreviousProcess);
   10912         if (mHeavyWeightProcess != null) {
   10913             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   10914         }
   10915 
   10916         return true;
   10917     }
   10918 
   10919     /**
   10920      * There are three ways to call this:
   10921      *  - no provider specified: dump all the providers
   10922      *  - a flattened component name that matched an existing provider was specified as the
   10923      *    first arg: dump that one provider
   10924      *  - the first arg isn't the flattened component name of an existing provider:
   10925      *    dump all providers whose component contains the first arg as a substring
   10926      */
   10927     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   10928             int opti, boolean dumpAll) {
   10929         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   10930     }
   10931 
   10932     static class ItemMatcher {
   10933         ArrayList<ComponentName> components;
   10934         ArrayList<String> strings;
   10935         ArrayList<Integer> objects;
   10936         boolean all;
   10937 
   10938         ItemMatcher() {
   10939             all = true;
   10940         }
   10941 
   10942         void build(String name) {
   10943             ComponentName componentName = ComponentName.unflattenFromString(name);
   10944             if (componentName != null) {
   10945                 if (components == null) {
   10946                     components = new ArrayList<ComponentName>();
   10947                 }
   10948                 components.add(componentName);
   10949                 all = false;
   10950             } else {
   10951                 int objectId = 0;
   10952                 // Not a '/' separated full component name; maybe an object ID?
   10953                 try {
   10954                     objectId = Integer.parseInt(name, 16);
   10955                     if (objects == null) {
   10956                         objects = new ArrayList<Integer>();
   10957                     }
   10958                     objects.add(objectId);
   10959                     all = false;
   10960                 } catch (RuntimeException e) {
   10961                     // Not an integer; just do string match.
   10962                     if (strings == null) {
   10963                         strings = new ArrayList<String>();
   10964                     }
   10965                     strings.add(name);
   10966                     all = false;
   10967                 }
   10968             }
   10969         }
   10970 
   10971         int build(String[] args, int opti) {
   10972             for (; opti<args.length; opti++) {
   10973                 String name = args[opti];
   10974                 if ("--".equals(name)) {
   10975                     return opti+1;
   10976                 }
   10977                 build(name);
   10978             }
   10979             return opti;
   10980         }
   10981 
   10982         boolean match(Object object, ComponentName comp) {
   10983             if (all) {
   10984                 return true;
   10985             }
   10986             if (components != null) {
   10987                 for (int i=0; i<components.size(); i++) {
   10988                     if (components.get(i).equals(comp)) {
   10989                         return true;
   10990                     }
   10991                 }
   10992             }
   10993             if (objects != null) {
   10994                 for (int i=0; i<objects.size(); i++) {
   10995                     if (System.identityHashCode(object) == objects.get(i)) {
   10996                         return true;
   10997                     }
   10998                 }
   10999             }
   11000             if (strings != null) {
   11001                 String flat = comp.flattenToString();
   11002                 for (int i=0; i<strings.size(); i++) {
   11003                     if (flat.contains(strings.get(i))) {
   11004                         return true;
   11005                     }
   11006                 }
   11007             }
   11008             return false;
   11009         }
   11010     }
   11011 
   11012     /**
   11013      * There are three things that cmd can be:
   11014      *  - a flattened component name that matches an existing activity
   11015      *  - the cmd arg isn't the flattened component name of an existing activity:
   11016      *    dump all activity whose component contains the cmd as a substring
   11017      *  - A hex number of the ActivityRecord object instance.
   11018      */
   11019     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   11020             int opti, boolean dumpAll) {
   11021         ArrayList<ActivityRecord> activities;
   11022 
   11023         synchronized (this) {
   11024             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   11025         }
   11026 
   11027         if (activities.size() <= 0) {
   11028             return false;
   11029         }
   11030 
   11031         String[] newArgs = new String[args.length - opti];
   11032         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   11033 
   11034         TaskRecord lastTask = null;
   11035         boolean needSep = false;
   11036         for (int i=activities.size()-1; i>=0; i--) {
   11037             ActivityRecord r = activities.get(i);
   11038             if (needSep) {
   11039                 pw.println();
   11040             }
   11041             needSep = true;
   11042             synchronized (this) {
   11043                 if (lastTask != r.task) {
   11044                     lastTask = r.task;
   11045                     pw.print("TASK "); pw.print(lastTask.affinity);
   11046                             pw.print(" id="); pw.println(lastTask.taskId);
   11047                     if (dumpAll) {
   11048                         lastTask.dump(pw, "  ");
   11049                     }
   11050                 }
   11051             }
   11052             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   11053         }
   11054         return true;
   11055     }
   11056 
   11057     /**
   11058      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   11059      * there is a thread associated with the activity.
   11060      */
   11061     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   11062             final ActivityRecord r, String[] args, boolean dumpAll) {
   11063         String innerPrefix = prefix + "  ";
   11064         synchronized (this) {
   11065             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   11066                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   11067                     pw.print(" pid=");
   11068                     if (r.app != null) pw.println(r.app.pid);
   11069                     else pw.println("(not running)");
   11070             if (dumpAll) {
   11071                 r.dump(pw, innerPrefix);
   11072             }
   11073         }
   11074         if (r.app != null && r.app.thread != null) {
   11075             // flush anything that is already in the PrintWriter since the thread is going
   11076             // to write to the file descriptor directly
   11077             pw.flush();
   11078             try {
   11079                 TransferPipe tp = new TransferPipe();
   11080                 try {
   11081                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   11082                             r.appToken, innerPrefix, args);
   11083                     tp.go(fd);
   11084                 } finally {
   11085                     tp.kill();
   11086                 }
   11087             } catch (IOException e) {
   11088                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   11089             } catch (RemoteException e) {
   11090                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   11091             }
   11092         }
   11093     }
   11094 
   11095     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11096             int opti, boolean dumpAll, String dumpPackage) {
   11097         boolean needSep = false;
   11098         boolean onlyHistory = false;
   11099         boolean printedAnything = false;
   11100 
   11101         if ("history".equals(dumpPackage)) {
   11102             if (opti < args.length && "-s".equals(args[opti])) {
   11103                 dumpAll = false;
   11104             }
   11105             onlyHistory = true;
   11106             dumpPackage = null;
   11107         }
   11108 
   11109         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   11110         if (!onlyHistory && dumpAll) {
   11111             if (mRegisteredReceivers.size() > 0) {
   11112                 boolean printed = false;
   11113                 Iterator it = mRegisteredReceivers.values().iterator();
   11114                 while (it.hasNext()) {
   11115                     ReceiverList r = (ReceiverList)it.next();
   11116                     if (dumpPackage != null && (r.app == null ||
   11117                             !dumpPackage.equals(r.app.info.packageName))) {
   11118                         continue;
   11119                     }
   11120                     if (!printed) {
   11121                         pw.println("  Registered Receivers:");
   11122                         needSep = true;
   11123                         printed = true;
   11124                         printedAnything = true;
   11125                     }
   11126                     pw.print("  * "); pw.println(r);
   11127                     r.dump(pw, "    ");
   11128                 }
   11129             }
   11130 
   11131             if (mReceiverResolver.dump(pw, needSep ?
   11132                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   11133                     "    ", dumpPackage, false)) {
   11134                 needSep = true;
   11135                 printedAnything = true;
   11136             }
   11137         }
   11138 
   11139         for (BroadcastQueue q : mBroadcastQueues) {
   11140             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   11141             printedAnything |= needSep;
   11142         }
   11143 
   11144         needSep = true;
   11145 
   11146         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   11147             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   11148                 if (needSep) {
   11149                     pw.println();
   11150                 }
   11151                 needSep = true;
   11152                 printedAnything = true;
   11153                 pw.print("  Sticky broadcasts for user ");
   11154                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   11155                 StringBuilder sb = new StringBuilder(128);
   11156                 for (Map.Entry<String, ArrayList<Intent>> ent
   11157                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   11158                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   11159                     if (dumpAll) {
   11160                         pw.println(":");
   11161                         ArrayList<Intent> intents = ent.getValue();
   11162                         final int N = intents.size();
   11163                         for (int i=0; i<N; i++) {
   11164                             sb.setLength(0);
   11165                             sb.append("    Intent: ");
   11166                             intents.get(i).toShortString(sb, false, true, false, false);
   11167                             pw.println(sb.toString());
   11168                             Bundle bundle = intents.get(i).getExtras();
   11169                             if (bundle != null) {
   11170                                 pw.print("      ");
   11171                                 pw.println(bundle.toString());
   11172                             }
   11173                         }
   11174                     } else {
   11175                         pw.println("");
   11176                     }
   11177                 }
   11178             }
   11179         }
   11180 
   11181         if (!onlyHistory && dumpAll) {
   11182             pw.println();
   11183             for (BroadcastQueue queue : mBroadcastQueues) {
   11184                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   11185                         + queue.mBroadcastsScheduled);
   11186             }
   11187             pw.println("  mHandler:");
   11188             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   11189             needSep = true;
   11190             printedAnything = true;
   11191         }
   11192 
   11193         if (!printedAnything) {
   11194             pw.println("  (nothing)");
   11195         }
   11196     }
   11197 
   11198     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11199             int opti, boolean dumpAll, String dumpPackage) {
   11200         boolean needSep;
   11201         boolean printedAnything = false;
   11202 
   11203         ItemMatcher matcher = new ItemMatcher();
   11204         matcher.build(args, opti);
   11205 
   11206         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   11207 
   11208         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   11209         printedAnything |= needSep;
   11210 
   11211         if (mLaunchingProviders.size() > 0) {
   11212             boolean printed = false;
   11213             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   11214                 ContentProviderRecord r = mLaunchingProviders.get(i);
   11215                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   11216                     continue;
   11217                 }
   11218                 if (!printed) {
   11219                     if (needSep) pw.println();
   11220                     needSep = true;
   11221                     pw.println("  Launching content providers:");
   11222                     printed = true;
   11223                     printedAnything = true;
   11224                 }
   11225                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   11226                         pw.println(r);
   11227             }
   11228         }
   11229 
   11230         if (mGrantedUriPermissions.size() > 0) {
   11231             boolean printed = false;
   11232             int dumpUid = -2;
   11233             if (dumpPackage != null) {
   11234                 try {
   11235                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   11236                 } catch (NameNotFoundException e) {
   11237                     dumpUid = -1;
   11238                 }
   11239             }
   11240             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   11241                 int uid = mGrantedUriPermissions.keyAt(i);
   11242                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   11243                     continue;
   11244                 }
   11245                 ArrayMap<Uri, UriPermission> perms
   11246                         = mGrantedUriPermissions.valueAt(i);
   11247                 if (!printed) {
   11248                     if (needSep) pw.println();
   11249                     needSep = true;
   11250                     pw.println("  Granted Uri Permissions:");
   11251                     printed = true;
   11252                     printedAnything = true;
   11253                 }
   11254                 pw.print("  * UID "); pw.print(uid);
   11255                         pw.println(" holds:");
   11256                 for (UriPermission perm : perms.values()) {
   11257                     pw.print("    "); pw.println(perm);
   11258                     if (dumpAll) {
   11259                         perm.dump(pw, "      ");
   11260                     }
   11261                 }
   11262             }
   11263         }
   11264 
   11265         if (!printedAnything) {
   11266             pw.println("  (nothing)");
   11267         }
   11268     }
   11269 
   11270     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11271             int opti, boolean dumpAll, String dumpPackage) {
   11272         boolean printed = false;
   11273 
   11274         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   11275 
   11276         if (mIntentSenderRecords.size() > 0) {
   11277             Iterator<WeakReference<PendingIntentRecord>> it
   11278                     = mIntentSenderRecords.values().iterator();
   11279             while (it.hasNext()) {
   11280                 WeakReference<PendingIntentRecord> ref = it.next();
   11281                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   11282                 if (dumpPackage != null && (rec == null
   11283                         || !dumpPackage.equals(rec.key.packageName))) {
   11284                     continue;
   11285                 }
   11286                 printed = true;
   11287                 if (rec != null) {
   11288                     pw.print("  * "); pw.println(rec);
   11289                     if (dumpAll) {
   11290                         rec.dump(pw, "    ");
   11291                     }
   11292                 } else {
   11293                     pw.print("  * "); pw.println(ref);
   11294                 }
   11295             }
   11296         }
   11297 
   11298         if (!printed) {
   11299             pw.println("  (nothing)");
   11300         }
   11301     }
   11302 
   11303     private static final int dumpProcessList(PrintWriter pw,
   11304             ActivityManagerService service, List list,
   11305             String prefix, String normalLabel, String persistentLabel,
   11306             String dumpPackage) {
   11307         int numPers = 0;
   11308         final int N = list.size()-1;
   11309         for (int i=N; i>=0; i--) {
   11310             ProcessRecord r = (ProcessRecord)list.get(i);
   11311             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   11312                 continue;
   11313             }
   11314             pw.println(String.format("%s%s #%2d: %s",
   11315                     prefix, (r.persistent ? persistentLabel : normalLabel),
   11316                     i, r.toString()));
   11317             if (r.persistent) {
   11318                 numPers++;
   11319             }
   11320         }
   11321         return numPers;
   11322     }
   11323 
   11324     private static final boolean dumpProcessOomList(PrintWriter pw,
   11325             ActivityManagerService service, List<ProcessRecord> origList,
   11326             String prefix, String normalLabel, String persistentLabel,
   11327             boolean inclDetails, String dumpPackage) {
   11328 
   11329         ArrayList<Pair<ProcessRecord, Integer>> list
   11330                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   11331         for (int i=0; i<origList.size(); i++) {
   11332             ProcessRecord r = origList.get(i);
   11333             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   11334                 continue;
   11335             }
   11336             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   11337         }
   11338 
   11339         if (list.size() <= 0) {
   11340             return false;
   11341         }
   11342 
   11343         Comparator<Pair<ProcessRecord, Integer>> comparator
   11344                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   11345             @Override
   11346             public int compare(Pair<ProcessRecord, Integer> object1,
   11347                     Pair<ProcessRecord, Integer> object2) {
   11348                 if (object1.first.setAdj != object2.first.setAdj) {
   11349                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   11350                 }
   11351                 if (object1.second.intValue() != object2.second.intValue()) {
   11352                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   11353                 }
   11354                 return 0;
   11355             }
   11356         };
   11357 
   11358         Collections.sort(list, comparator);
   11359 
   11360         final long curRealtime = SystemClock.elapsedRealtime();
   11361         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   11362         final long curUptime = SystemClock.uptimeMillis();
   11363         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   11364 
   11365         for (int i=list.size()-1; i>=0; i--) {
   11366             ProcessRecord r = list.get(i).first;
   11367             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   11368             char schedGroup;
   11369             switch (r.setSchedGroup) {
   11370                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   11371                     schedGroup = 'B';
   11372                     break;
   11373                 case Process.THREAD_GROUP_DEFAULT:
   11374                     schedGroup = 'F';
   11375                     break;
   11376                 default:
   11377                     schedGroup = '?';
   11378                     break;
   11379             }
   11380             char foreground;
   11381             if (r.foregroundActivities) {
   11382                 foreground = 'A';
   11383             } else if (r.foregroundServices) {
   11384                 foreground = 'S';
   11385             } else {
   11386                 foreground = ' ';
   11387             }
   11388             String procState = ProcessList.makeProcStateString(r.curProcState);
   11389             pw.print(prefix);
   11390             pw.print(r.persistent ? persistentLabel : normalLabel);
   11391             pw.print(" #");
   11392             int num = (origList.size()-1)-list.get(i).second;
   11393             if (num < 10) pw.print(' ');
   11394             pw.print(num);
   11395             pw.print(": ");
   11396             pw.print(oomAdj);
   11397             pw.print(' ');
   11398             pw.print(schedGroup);
   11399             pw.print('/');
   11400             pw.print(foreground);
   11401             pw.print('/');
   11402             pw.print(procState);
   11403             pw.print(" trm:");
   11404             if (r.trimMemoryLevel < 10) pw.print(' ');
   11405             pw.print(r.trimMemoryLevel);
   11406             pw.print(' ');
   11407             pw.print(r.toShortString());
   11408             pw.print(" (");
   11409             pw.print(r.adjType);
   11410             pw.println(')');
   11411             if (r.adjSource != null || r.adjTarget != null) {
   11412                 pw.print(prefix);
   11413                 pw.print("    ");
   11414                 if (r.adjTarget instanceof ComponentName) {
   11415                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   11416                 } else if (r.adjTarget != null) {
   11417                     pw.print(r.adjTarget.toString());
   11418                 } else {
   11419                     pw.print("{null}");
   11420                 }
   11421                 pw.print("<=");
   11422                 if (r.adjSource instanceof ProcessRecord) {
   11423                     pw.print("Proc{");
   11424                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   11425                     pw.println("}");
   11426                 } else if (r.adjSource != null) {
   11427                     pw.println(r.adjSource.toString());
   11428                 } else {
   11429                     pw.println("{null}");
   11430                 }
   11431             }
   11432             if (inclDetails) {
   11433                 pw.print(prefix);
   11434                 pw.print("    ");
   11435                 pw.print("oom: max="); pw.print(r.maxAdj);
   11436                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   11437                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   11438                 pw.print(" cur="); pw.print(r.curAdj);
   11439                 pw.print(" set="); pw.println(r.setAdj);
   11440                 pw.print(prefix);
   11441                 pw.print("    ");
   11442                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   11443                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   11444                 pw.print(" lastPss="); pw.print(r.lastPss);
   11445                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   11446                 pw.print(prefix);
   11447                 pw.print("    ");
   11448                 pw.print("keeping="); pw.print(r.keeping);
   11449                 pw.print(" cached="); pw.print(r.cached);
   11450                 pw.print(" empty="); pw.print(r.empty);
   11451                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   11452 
   11453                 if (!r.keeping) {
   11454                     if (r.lastWakeTime != 0) {
   11455                         long wtime;
   11456                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   11457                         synchronized (stats) {
   11458                             wtime = stats.getProcessWakeTime(r.info.uid,
   11459                                     r.pid, curRealtime);
   11460                         }
   11461                         long timeUsed = wtime - r.lastWakeTime;
   11462                         pw.print(prefix);
   11463                         pw.print("    ");
   11464                         pw.print("keep awake over ");
   11465                         TimeUtils.formatDuration(realtimeSince, pw);
   11466                         pw.print(" used ");
   11467                         TimeUtils.formatDuration(timeUsed, pw);
   11468                         pw.print(" (");
   11469                         pw.print((timeUsed*100)/realtimeSince);
   11470                         pw.println("%)");
   11471                     }
   11472                     if (r.lastCpuTime != 0) {
   11473                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   11474                         pw.print(prefix);
   11475                         pw.print("    ");
   11476                         pw.print("run cpu over ");
   11477                         TimeUtils.formatDuration(uptimeSince, pw);
   11478                         pw.print(" used ");
   11479                         TimeUtils.formatDuration(timeUsed, pw);
   11480                         pw.print(" (");
   11481                         pw.print((timeUsed*100)/uptimeSince);
   11482                         pw.println("%)");
   11483                     }
   11484                 }
   11485             }
   11486         }
   11487         return true;
   11488     }
   11489 
   11490     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   11491         ArrayList<ProcessRecord> procs;
   11492         synchronized (this) {
   11493             if (args != null && args.length > start
   11494                     && args[start].charAt(0) != '-') {
   11495                 procs = new ArrayList<ProcessRecord>();
   11496                 int pid = -1;
   11497                 try {
   11498                     pid = Integer.parseInt(args[start]);
   11499                 } catch (NumberFormatException e) {
   11500 
   11501                 }
   11502                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   11503                     ProcessRecord proc = mLruProcesses.get(i);
   11504                     if (proc.pid == pid) {
   11505                         procs.add(proc);
   11506                     } else if (proc.processName.equals(args[start])) {
   11507                         procs.add(proc);
   11508                     }
   11509                 }
   11510                 if (procs.size() <= 0) {
   11511                     pw.println("No process found for: " + args[start]);
   11512                     return null;
   11513                 }
   11514             } else {
   11515                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   11516             }
   11517         }
   11518         return procs;
   11519     }
   11520 
   11521     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   11522             PrintWriter pw, String[] args) {
   11523         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11524         if (procs == null) {
   11525             return;
   11526         }
   11527 
   11528         long uptime = SystemClock.uptimeMillis();
   11529         long realtime = SystemClock.elapsedRealtime();
   11530         pw.println("Applications Graphics Acceleration Info:");
   11531         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11532 
   11533         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11534             ProcessRecord r = procs.get(i);
   11535             if (r.thread != null) {
   11536                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   11537                 pw.flush();
   11538                 try {
   11539                     TransferPipe tp = new TransferPipe();
   11540                     try {
   11541                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   11542                         tp.go(fd);
   11543                     } finally {
   11544                         tp.kill();
   11545                     }
   11546                 } catch (IOException e) {
   11547                     pw.println("Failure while dumping the app: " + r);
   11548                     pw.flush();
   11549                 } catch (RemoteException e) {
   11550                     pw.println("Got a RemoteException while dumping the app " + r);
   11551                     pw.flush();
   11552                 }
   11553             }
   11554         }
   11555     }
   11556 
   11557     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   11558         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11559         if (procs == null) {
   11560             return;
   11561         }
   11562 
   11563         pw.println("Applications Database Info:");
   11564 
   11565         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11566             ProcessRecord r = procs.get(i);
   11567             if (r.thread != null) {
   11568                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   11569                 pw.flush();
   11570                 try {
   11571                     TransferPipe tp = new TransferPipe();
   11572                     try {
   11573                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   11574                         tp.go(fd);
   11575                     } finally {
   11576                         tp.kill();
   11577                     }
   11578                 } catch (IOException e) {
   11579                     pw.println("Failure while dumping the app: " + r);
   11580                     pw.flush();
   11581                 } catch (RemoteException e) {
   11582                     pw.println("Got a RemoteException while dumping the app " + r);
   11583                     pw.flush();
   11584                 }
   11585             }
   11586         }
   11587     }
   11588 
   11589     final static class MemItem {
   11590         final boolean isProc;
   11591         final String label;
   11592         final String shortLabel;
   11593         final long pss;
   11594         final int id;
   11595         final boolean hasActivities;
   11596         ArrayList<MemItem> subitems;
   11597 
   11598         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   11599                 boolean _hasActivities) {
   11600             isProc = true;
   11601             label = _label;
   11602             shortLabel = _shortLabel;
   11603             pss = _pss;
   11604             id = _id;
   11605             hasActivities = _hasActivities;
   11606         }
   11607 
   11608         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   11609             isProc = false;
   11610             label = _label;
   11611             shortLabel = _shortLabel;
   11612             pss = _pss;
   11613             id = _id;
   11614             hasActivities = false;
   11615         }
   11616     }
   11617 
   11618     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   11619             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   11620         if (sort && !isCompact) {
   11621             Collections.sort(items, new Comparator<MemItem>() {
   11622                 @Override
   11623                 public int compare(MemItem lhs, MemItem rhs) {
   11624                     if (lhs.pss < rhs.pss) {
   11625                         return 1;
   11626                     } else if (lhs.pss > rhs.pss) {
   11627                         return -1;
   11628                     }
   11629                     return 0;
   11630                 }
   11631             });
   11632         }
   11633 
   11634         for (int i=0; i<items.size(); i++) {
   11635             MemItem mi = items.get(i);
   11636             if (!isCompact) {
   11637                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   11638             } else if (mi.isProc) {
   11639                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   11640                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   11641                 pw.println(mi.hasActivities ? ",a" : ",e");
   11642             } else {
   11643                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   11644                 pw.println(mi.pss);
   11645             }
   11646             if (mi.subitems != null) {
   11647                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   11648                         true, isCompact);
   11649             }
   11650         }
   11651     }
   11652 
   11653     // These are in KB.
   11654     static final long[] DUMP_MEM_BUCKETS = new long[] {
   11655         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   11656         120*1024, 160*1024, 200*1024,
   11657         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   11658         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   11659     };
   11660 
   11661     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   11662             boolean stackLike) {
   11663         int start = label.lastIndexOf('.');
   11664         if (start >= 0) start++;
   11665         else start = 0;
   11666         int end = label.length();
   11667         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   11668             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   11669                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   11670                 out.append(bucket);
   11671                 out.append(stackLike ? "MB." : "MB ");
   11672                 out.append(label, start, end);
   11673                 return;
   11674             }
   11675         }
   11676         out.append(memKB/1024);
   11677         out.append(stackLike ? "MB." : "MB ");
   11678         out.append(label, start, end);
   11679     }
   11680 
   11681     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   11682             ProcessList.NATIVE_ADJ,
   11683             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   11684             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   11685             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   11686             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   11687             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   11688     };
   11689     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   11690             "Native",
   11691             "System", "Persistent", "Foreground",
   11692             "Visible", "Perceptible",
   11693             "Heavy Weight", "Backup",
   11694             "A Services", "Home",
   11695             "Previous", "B Services", "Cached"
   11696     };
   11697     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   11698             "native",
   11699             "sys", "pers", "fore",
   11700             "vis", "percept",
   11701             "heavy", "backup",
   11702             "servicea", "home",
   11703             "prev", "serviceb", "cached"
   11704     };
   11705 
   11706     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   11707             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   11708         boolean dumpDetails = false;
   11709         boolean dumpFullDetails = false;
   11710         boolean dumpDalvik = false;
   11711         boolean oomOnly = false;
   11712         boolean isCompact = false;
   11713 
   11714         int opti = 0;
   11715         while (opti < args.length) {
   11716             String opt = args[opti];
   11717             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   11718                 break;
   11719             }
   11720             opti++;
   11721             if ("-a".equals(opt)) {
   11722                 dumpDetails = true;
   11723                 dumpFullDetails = true;
   11724                 dumpDalvik = true;
   11725             } else if ("-d".equals(opt)) {
   11726                 dumpDalvik = true;
   11727             } else if ("-c".equals(opt)) {
   11728                 isCompact = true;
   11729             } else if ("--oom".equals(opt)) {
   11730                 oomOnly = true;
   11731             } else if ("-h".equals(opt)) {
   11732                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   11733                 pw.println("  -a: include all available information for each process.");
   11734                 pw.println("  -d: include dalvik details when dumping process details.");
   11735                 pw.println("  -c: dump in a compact machine-parseable representation.");
   11736                 pw.println("  --oom: only show processes organized by oom adj.");
   11737                 pw.println("If [process] is specified it can be the name or ");
   11738                 pw.println("pid of a specific process to dump.");
   11739                 return;
   11740             } else {
   11741                 pw.println("Unknown argument: " + opt + "; use -h for help");
   11742             }
   11743         }
   11744 
   11745         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   11746         if (procs == null) {
   11747             return;
   11748         }
   11749 
   11750         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   11751         long uptime = SystemClock.uptimeMillis();
   11752         long realtime = SystemClock.elapsedRealtime();
   11753 
   11754         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
   11755             dumpDetails = true;
   11756         }
   11757 
   11758         if (isCheckinRequest || isCompact) {
   11759             // short checkin version
   11760             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   11761         } else {
   11762             pw.println("Applications Memory Usage (kB):");
   11763             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11764         }
   11765 
   11766         String[] innerArgs = new String[args.length-opti];
   11767         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   11768 
   11769         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   11770         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   11771         long nativePss=0, dalvikPss=0, otherPss=0;
   11772         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   11773 
   11774         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   11775         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   11776                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   11777         final long[] tmpLong = new long[1];
   11778 
   11779         long totalPss = 0;
   11780         long cachedPss = 0;
   11781 
   11782         Debug.MemoryInfo mi = null;
   11783         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11784             final ProcessRecord r = procs.get(i);
   11785             final IApplicationThread thread;
   11786             final int pid;
   11787             final int oomAdj;
   11788             final boolean hasActivities;
   11789             synchronized (this) {
   11790                 thread = r.thread;
   11791                 pid = r.pid;
   11792                 oomAdj = r.getSetAdjWithServices();
   11793                 hasActivities = r.hasActivities;
   11794             }
   11795             if (thread != null) {
   11796                 if (!isCheckinRequest && dumpDetails) {
   11797                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   11798                 }
   11799                 if (mi == null) {
   11800                     mi = new Debug.MemoryInfo();
   11801                 }
   11802                 if (dumpDetails || (!brief && !oomOnly)) {
   11803                     Debug.getMemoryInfo(pid, mi);
   11804                 } else {
   11805                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   11806                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   11807                 }
   11808                 if (dumpDetails) {
   11809                     try {
   11810                         pw.flush();
   11811                         thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   11812                                 dumpDalvik, innerArgs);
   11813                     } catch (RemoteException e) {
   11814                         if (!isCheckinRequest) {
   11815                             pw.println("Got RemoteException!");
   11816                             pw.flush();
   11817                         }
   11818                     }
   11819                 }
   11820 
   11821                 final long myTotalPss = mi.getTotalPss();
   11822                 final long myTotalUss = mi.getTotalUss();
   11823 
   11824                 synchronized (this) {
   11825                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   11826                         // Record this for posterity if the process has been stable.
   11827                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   11828                     }
   11829                 }
   11830 
   11831                 if (!isCheckinRequest && mi != null) {
   11832                     totalPss += myTotalPss;
   11833                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   11834                             (hasActivities ? " / activities)" : ")"),
   11835                             r.processName, myTotalPss, pid, hasActivities);
   11836                     procMems.add(pssItem);
   11837                     procMemsMap.put(pid, pssItem);
   11838 
   11839                     nativePss += mi.nativePss;
   11840                     dalvikPss += mi.dalvikPss;
   11841                     otherPss += mi.otherPss;
   11842                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   11843                         long mem = mi.getOtherPss(j);
   11844                         miscPss[j] += mem;
   11845                         otherPss -= mem;
   11846                     }
   11847 
   11848                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   11849                         cachedPss += myTotalPss;
   11850                     }
   11851 
   11852                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   11853                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   11854                                 || oomIndex == (oomPss.length-1)) {
   11855                             oomPss[oomIndex] += myTotalPss;
   11856                             if (oomProcs[oomIndex] == null) {
   11857                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   11858                             }
   11859                             oomProcs[oomIndex].add(pssItem);
   11860                             break;
   11861                         }
   11862                     }
   11863                 }
   11864             }
   11865         }
   11866 
   11867         if (!isCheckinRequest && procs.size() > 1) {
   11868             // If we are showing aggregations, also look for native processes to
   11869             // include so that our aggregations are more accurate.
   11870             updateCpuStatsNow();
   11871             synchronized (mProcessCpuThread) {
   11872                 final int N = mProcessCpuTracker.countStats();
   11873                 for (int i=0; i<N; i++) {
   11874                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   11875                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   11876                         if (mi == null) {
   11877                             mi = new Debug.MemoryInfo();
   11878                         }
   11879                         if (!brief && !oomOnly) {
   11880                             Debug.getMemoryInfo(st.pid, mi);
   11881                         } else {
   11882                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
   11883                             mi.nativePrivateDirty = (int)tmpLong[0];
   11884                         }
   11885 
   11886                         final long myTotalPss = mi.getTotalPss();
   11887                         totalPss += myTotalPss;
   11888 
   11889                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   11890                                 st.name, myTotalPss, st.pid, false);
   11891                         procMems.add(pssItem);
   11892 
   11893                         nativePss += mi.nativePss;
   11894                         dalvikPss += mi.dalvikPss;
   11895                         otherPss += mi.otherPss;
   11896                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   11897                             long mem = mi.getOtherPss(j);
   11898                             miscPss[j] += mem;
   11899                             otherPss -= mem;
   11900                         }
   11901                         oomPss[0] += myTotalPss;
   11902                         if (oomProcs[0] == null) {
   11903                             oomProcs[0] = new ArrayList<MemItem>();
   11904                         }
   11905                         oomProcs[0].add(pssItem);
   11906                     }
   11907                 }
   11908             }
   11909 
   11910             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   11911 
   11912             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   11913             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   11914             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   11915             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   11916                 String label = Debug.MemoryInfo.getOtherLabel(j);
   11917                 catMems.add(new MemItem(label, label, miscPss[j], j));
   11918             }
   11919 
   11920             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   11921             for (int j=0; j<oomPss.length; j++) {
   11922                 if (oomPss[j] != 0) {
   11923                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   11924                             : DUMP_MEM_OOM_LABEL[j];
   11925                     MemItem item = new MemItem(label, label, oomPss[j],
   11926                             DUMP_MEM_OOM_ADJ[j]);
   11927                     item.subitems = oomProcs[j];
   11928                     oomMems.add(item);
   11929                 }
   11930             }
   11931 
   11932             if (!brief && !oomOnly && !isCompact) {
   11933                 pw.println();
   11934                 pw.println("Total PSS by process:");
   11935                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   11936                 pw.println();
   11937             }
   11938             if (!isCompact) {
   11939                 pw.println("Total PSS by OOM adjustment:");
   11940             }
   11941             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   11942             if (!brief && !oomOnly) {
   11943                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   11944                 if (!isCompact) {
   11945                     out.println();
   11946                     out.println("Total PSS by category:");
   11947                 }
   11948                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   11949             }
   11950             if (!isCompact) {
   11951                 pw.println();
   11952             }
   11953             MemInfoReader memInfo = new MemInfoReader();
   11954             memInfo.readMemInfo();
   11955             if (!brief) {
   11956                 if (!isCompact) {
   11957                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   11958                     pw.println(" kB");
   11959                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   11960                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   11961                             pw.print(cachedPss); pw.print(" cached pss + ");
   11962                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
   11963                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   11964                 } else {
   11965                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   11966                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   11967                             + memInfo.getFreeSizeKb()); pw.print(",");
   11968                     pw.println(totalPss - cachedPss);
   11969                 }
   11970             }
   11971             if (!isCompact) {
   11972                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   11973                         + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
   11974                         + memInfo.getSlabSizeKb()); pw.print(" kB (");
   11975                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   11976                         pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
   11977                         pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
   11978                         pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
   11979                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   11980                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   11981                         - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
   11982                         - memInfo.getSlabSizeKb()); pw.println(" kB");
   11983             }
   11984             if (!brief) {
   11985                 if (memInfo.getZramTotalSizeKb() != 0) {
   11986                     if (!isCompact) {
   11987                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   11988                                 pw.print(" kB physical used for ");
   11989                                 pw.print(memInfo.getSwapTotalSizeKb()
   11990                                         - memInfo.getSwapFreeSizeKb());
   11991                                 pw.print(" kB in swap (");
   11992                                 pw.print(memInfo.getSwapTotalSizeKb());
   11993                                 pw.println(" kB total swap)");
   11994                     } else {
   11995                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   11996                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   11997                                 pw.println(memInfo.getSwapFreeSizeKb());
   11998                     }
   11999                 }
   12000                 final int[] SINGLE_LONG_FORMAT = new int[] {
   12001                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   12002                 };
   12003                 long[] longOut = new long[1];
   12004                 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   12005                         SINGLE_LONG_FORMAT, null, longOut, null);
   12006                 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12007                 longOut[0] = 0;
   12008                 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   12009                         SINGLE_LONG_FORMAT, null, longOut, null);
   12010                 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12011                 longOut[0] = 0;
   12012                 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   12013                         SINGLE_LONG_FORMAT, null, longOut, null);
   12014                 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12015                 longOut[0] = 0;
   12016                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   12017                         SINGLE_LONG_FORMAT, null, longOut, null);
   12018                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12019                 if (!isCompact) {
   12020                     if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
   12021                         pw.print("      KSM: "); pw.print(sharing);
   12022                                 pw.print(" kB saved from shared ");
   12023                                 pw.print(shared); pw.println(" kB");
   12024                         pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   12025                                 pw.print(voltile); pw.println(" kB volatile");
   12026                     }
   12027                     pw.print("   Tuning: ");
   12028                     pw.print(ActivityManager.staticGetMemoryClass());
   12029                     pw.print(" (large ");
   12030                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12031                     pw.print("), oom ");
   12032                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12033                     pw.print(" kB");
   12034                     pw.print(", restore limit ");
   12035                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   12036                     pw.print(" kB");
   12037                     if (ActivityManager.isLowRamDeviceStatic()) {
   12038                         pw.print(" (low-ram)");
   12039                     }
   12040                     if (ActivityManager.isHighEndGfx()) {
   12041                         pw.print(" (high-end-gfx)");
   12042                     }
   12043                     pw.println();
   12044                 } else {
   12045                     pw.print("ksm,"); pw.print(sharing); pw.print(",");
   12046                     pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
   12047                     pw.println(voltile);
   12048                     pw.print("tuning,");
   12049                     pw.print(ActivityManager.staticGetMemoryClass());
   12050                     pw.print(',');
   12051                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12052                     pw.print(',');
   12053                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12054                     if (ActivityManager.isLowRamDeviceStatic()) {
   12055                         pw.print(",low-ram");
   12056                     }
   12057                     if (ActivityManager.isHighEndGfx()) {
   12058                         pw.print(",high-end-gfx");
   12059                     }
   12060                     pw.println();
   12061                 }
   12062             }
   12063         }
   12064     }
   12065 
   12066     /**
   12067      * Searches array of arguments for the specified string
   12068      * @param args array of argument strings
   12069      * @param value value to search for
   12070      * @return true if the value is contained in the array
   12071      */
   12072     private static boolean scanArgs(String[] args, String value) {
   12073         if (args != null) {
   12074             for (String arg : args) {
   12075                 if (value.equals(arg)) {
   12076                     return true;
   12077                 }
   12078             }
   12079         }
   12080         return false;
   12081     }
   12082 
   12083     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   12084             ContentProviderRecord cpr, boolean always) {
   12085         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   12086 
   12087         if (!inLaunching || always) {
   12088             synchronized (cpr) {
   12089                 cpr.launchingApp = null;
   12090                 cpr.notifyAll();
   12091             }
   12092             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   12093             String names[] = cpr.info.authority.split(";");
   12094             for (int j = 0; j < names.length; j++) {
   12095                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   12096             }
   12097         }
   12098 
   12099         for (int i=0; i<cpr.connections.size(); i++) {
   12100             ContentProviderConnection conn = cpr.connections.get(i);
   12101             if (conn.waiting) {
   12102                 // If this connection is waiting for the provider, then we don't
   12103                 // need to mess with its process unless we are always removing
   12104                 // or for some reason the provider is not currently launching.
   12105                 if (inLaunching && !always) {
   12106                     continue;
   12107                 }
   12108             }
   12109             ProcessRecord capp = conn.client;
   12110             conn.dead = true;
   12111             if (conn.stableCount > 0) {
   12112                 if (!capp.persistent && capp.thread != null
   12113                         && capp.pid != 0
   12114                         && capp.pid != MY_PID) {
   12115                     killUnneededProcessLocked(capp, "depends on provider "
   12116                             + cpr.name.flattenToShortString()
   12117                             + " in dying proc " + (proc != null ? proc.processName : "??"));
   12118                 }
   12119             } else if (capp.thread != null && conn.provider.provider != null) {
   12120                 try {
   12121                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   12122                 } catch (RemoteException e) {
   12123                 }
   12124                 // In the protocol here, we don't expect the client to correctly
   12125                 // clean up this connection, we'll just remove it.
   12126                 cpr.connections.remove(i);
   12127                 conn.client.conProviders.remove(conn);
   12128             }
   12129         }
   12130 
   12131         if (inLaunching && always) {
   12132             mLaunchingProviders.remove(cpr);
   12133         }
   12134         return inLaunching;
   12135     }
   12136 
   12137     /**
   12138      * Main code for cleaning up a process when it has gone away.  This is
   12139      * called both as a result of the process dying, or directly when stopping
   12140      * a process when running in single process mode.
   12141      */
   12142     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   12143             boolean restarting, boolean allowRestart, int index) {
   12144         if (index >= 0) {
   12145             removeLruProcessLocked(app);
   12146         }
   12147 
   12148         mProcessesToGc.remove(app);
   12149         mPendingPssProcesses.remove(app);
   12150 
   12151         // Dismiss any open dialogs.
   12152         if (app.crashDialog != null && !app.forceCrashReport) {
   12153             app.crashDialog.dismiss();
   12154             app.crashDialog = null;
   12155         }
   12156         if (app.anrDialog != null) {
   12157             app.anrDialog.dismiss();
   12158             app.anrDialog = null;
   12159         }
   12160         if (app.waitDialog != null) {
   12161             app.waitDialog.dismiss();
   12162             app.waitDialog = null;
   12163         }
   12164 
   12165         app.crashing = false;
   12166         app.notResponding = false;
   12167 
   12168         app.resetPackageList(mProcessStats);
   12169         app.unlinkDeathRecipient();
   12170         app.makeInactive(mProcessStats);
   12171         app.forcingToForeground = null;
   12172         app.foregroundServices = false;
   12173         app.foregroundActivities = false;
   12174         app.hasShownUi = false;
   12175         app.hasAboveClient = false;
   12176 
   12177         mServices.killServicesLocked(app, allowRestart);
   12178 
   12179         boolean restart = false;
   12180 
   12181         // Remove published content providers.
   12182         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   12183             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   12184             final boolean always = app.bad || !allowRestart;
   12185             if (removeDyingProviderLocked(app, cpr, always) || always) {
   12186                 // We left the provider in the launching list, need to
   12187                 // restart it.
   12188                 restart = true;
   12189             }
   12190 
   12191             cpr.provider = null;
   12192             cpr.proc = null;
   12193         }
   12194         app.pubProviders.clear();
   12195 
   12196         // Take care of any launching providers waiting for this process.
   12197         if (checkAppInLaunchingProvidersLocked(app, false)) {
   12198             restart = true;
   12199         }
   12200 
   12201         // Unregister from connected content providers.
   12202         if (!app.conProviders.isEmpty()) {
   12203             for (int i=0; i<app.conProviders.size(); i++) {
   12204                 ContentProviderConnection conn = app.conProviders.get(i);
   12205                 conn.provider.connections.remove(conn);
   12206             }
   12207             app.conProviders.clear();
   12208         }
   12209 
   12210         // At this point there may be remaining entries in mLaunchingProviders
   12211         // where we were the only one waiting, so they are no longer of use.
   12212         // Look for these and clean up if found.
   12213         // XXX Commented out for now.  Trying to figure out a way to reproduce
   12214         // the actual situation to identify what is actually going on.
   12215         if (false) {
   12216             for (int i=0; i<mLaunchingProviders.size(); i++) {
   12217                 ContentProviderRecord cpr = (ContentProviderRecord)
   12218                         mLaunchingProviders.get(i);
   12219                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   12220                     synchronized (cpr) {
   12221                         cpr.launchingApp = null;
   12222                         cpr.notifyAll();
   12223                     }
   12224                 }
   12225             }
   12226         }
   12227 
   12228         skipCurrentReceiverLocked(app);
   12229 
   12230         // Unregister any receivers.
   12231         for (int i=app.receivers.size()-1; i>=0; i--) {
   12232             removeReceiverLocked(app.receivers.valueAt(i));
   12233         }
   12234         app.receivers.clear();
   12235 
   12236         // If the app is undergoing backup, tell the backup manager about it
   12237         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   12238             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   12239                     + mBackupTarget.appInfo + " died during backup");
   12240             try {
   12241                 IBackupManager bm = IBackupManager.Stub.asInterface(
   12242                         ServiceManager.getService(Context.BACKUP_SERVICE));
   12243                 bm.agentDisconnected(app.info.packageName);
   12244             } catch (RemoteException e) {
   12245                 // can't happen; backup manager is local
   12246             }
   12247         }
   12248 
   12249         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   12250             ProcessChangeItem item = mPendingProcessChanges.get(i);
   12251             if (item.pid == app.pid) {
   12252                 mPendingProcessChanges.remove(i);
   12253                 mAvailProcessChanges.add(item);
   12254             }
   12255         }
   12256         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   12257 
   12258         // If the caller is restarting this app, then leave it in its
   12259         // current lists and let the caller take care of it.
   12260         if (restarting) {
   12261             return;
   12262         }
   12263 
   12264         if (!app.persistent || app.isolated) {
   12265             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   12266                     "Removing non-persistent process during cleanup: " + app);
   12267             mProcessNames.remove(app.processName, app.uid);
   12268             mIsolatedProcesses.remove(app.uid);
   12269             if (mHeavyWeightProcess == app) {
   12270                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   12271                         mHeavyWeightProcess.userId, 0));
   12272                 mHeavyWeightProcess = null;
   12273             }
   12274         } else if (!app.removed) {
   12275             // This app is persistent, so we need to keep its record around.
   12276             // If it is not already on the pending app list, add it there
   12277             // and start a new process for it.
   12278             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   12279                 mPersistentStartingProcesses.add(app);
   12280                 restart = true;
   12281             }
   12282         }
   12283         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   12284                 "Clean-up removing on hold: " + app);
   12285         mProcessesOnHold.remove(app);
   12286 
   12287         if (app == mHomeProcess) {
   12288             mHomeProcess = null;
   12289         }
   12290         if (app == mPreviousProcess) {
   12291             mPreviousProcess = null;
   12292         }
   12293 
   12294         if (restart && !app.isolated) {
   12295             // We have components that still need to be running in the
   12296             // process, so re-launch it.
   12297             mProcessNames.put(app.processName, app.uid, app);
   12298             startProcessLocked(app, "restart", app.processName);
   12299         } else if (app.pid > 0 && app.pid != MY_PID) {
   12300             // Goodbye!
   12301             synchronized (mPidsSelfLocked) {
   12302                 mPidsSelfLocked.remove(app.pid);
   12303                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   12304             }
   12305             app.setPid(0);
   12306         }
   12307     }
   12308 
   12309     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   12310         // Look through the content providers we are waiting to have launched,
   12311         // and if any run in this process then either schedule a restart of
   12312         // the process or kill the client waiting for it if this process has
   12313         // gone bad.
   12314         int NL = mLaunchingProviders.size();
   12315         boolean restart = false;
   12316         for (int i=0; i<NL; i++) {
   12317             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   12318             if (cpr.launchingApp == app) {
   12319                 if (!alwaysBad && !app.bad) {
   12320                     restart = true;
   12321                 } else {
   12322                     removeDyingProviderLocked(app, cpr, true);
   12323                     // cpr should have been removed from mLaunchingProviders
   12324                     NL = mLaunchingProviders.size();
   12325                     i--;
   12326                 }
   12327             }
   12328         }
   12329         return restart;
   12330     }
   12331 
   12332     // =========================================================
   12333     // SERVICES
   12334     // =========================================================
   12335 
   12336     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   12337             int flags) {
   12338         enforceNotIsolatedCaller("getServices");
   12339         synchronized (this) {
   12340             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   12341         }
   12342     }
   12343 
   12344     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   12345         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   12346         synchronized (this) {
   12347             return mServices.getRunningServiceControlPanelLocked(name);
   12348         }
   12349     }
   12350 
   12351     public ComponentName startService(IApplicationThread caller, Intent service,
   12352             String resolvedType, int userId) {
   12353         enforceNotIsolatedCaller("startService");
   12354         // Refuse possible leaked file descriptors
   12355         if (service != null && service.hasFileDescriptors() == true) {
   12356             throw new IllegalArgumentException("File descriptors passed in Intent");
   12357         }
   12358 
   12359         if (DEBUG_SERVICE)
   12360             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   12361         synchronized(this) {
   12362             final int callingPid = Binder.getCallingPid();
   12363             final int callingUid = Binder.getCallingUid();
   12364             checkValidCaller(callingUid, userId);
   12365             final long origId = Binder.clearCallingIdentity();
   12366             ComponentName res = mServices.startServiceLocked(caller, service,
   12367                     resolvedType, callingPid, callingUid, userId);
   12368             Binder.restoreCallingIdentity(origId);
   12369             return res;
   12370         }
   12371     }
   12372 
   12373     ComponentName startServiceInPackage(int uid,
   12374             Intent service, String resolvedType, int userId) {
   12375         synchronized(this) {
   12376             if (DEBUG_SERVICE)
   12377                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   12378             final long origId = Binder.clearCallingIdentity();
   12379             ComponentName res = mServices.startServiceLocked(null, service,
   12380                     resolvedType, -1, uid, userId);
   12381             Binder.restoreCallingIdentity(origId);
   12382             return res;
   12383         }
   12384     }
   12385 
   12386     public int stopService(IApplicationThread caller, Intent service,
   12387             String resolvedType, int userId) {
   12388         enforceNotIsolatedCaller("stopService");
   12389         // Refuse possible leaked file descriptors
   12390         if (service != null && service.hasFileDescriptors() == true) {
   12391             throw new IllegalArgumentException("File descriptors passed in Intent");
   12392         }
   12393 
   12394         checkValidCaller(Binder.getCallingUid(), userId);
   12395 
   12396         synchronized(this) {
   12397             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   12398         }
   12399     }
   12400 
   12401     public IBinder peekService(Intent service, String resolvedType) {
   12402         enforceNotIsolatedCaller("peekService");
   12403         // Refuse possible leaked file descriptors
   12404         if (service != null && service.hasFileDescriptors() == true) {
   12405             throw new IllegalArgumentException("File descriptors passed in Intent");
   12406         }
   12407         synchronized(this) {
   12408             return mServices.peekServiceLocked(service, resolvedType);
   12409         }
   12410     }
   12411 
   12412     public boolean stopServiceToken(ComponentName className, IBinder token,
   12413             int startId) {
   12414         synchronized(this) {
   12415             return mServices.stopServiceTokenLocked(className, token, startId);
   12416         }
   12417     }
   12418 
   12419     public void setServiceForeground(ComponentName className, IBinder token,
   12420             int id, Notification notification, boolean removeNotification) {
   12421         synchronized(this) {
   12422             mServices.setServiceForegroundLocked(className, token, id, notification,
   12423                     removeNotification);
   12424         }
   12425     }
   12426 
   12427     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   12428             boolean requireFull, String name, String callerPackage) {
   12429         final int callingUserId = UserHandle.getUserId(callingUid);
   12430         if (callingUserId != userId) {
   12431             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   12432                 if ((requireFull || checkComponentPermission(
   12433                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12434                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
   12435                         && checkComponentPermission(
   12436                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   12437                                 callingPid, callingUid, -1, true)
   12438                                 != PackageManager.PERMISSION_GRANTED) {
   12439                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   12440                         // In this case, they would like to just execute as their
   12441                         // owner user instead of failing.
   12442                         userId = callingUserId;
   12443                     } else {
   12444                         StringBuilder builder = new StringBuilder(128);
   12445                         builder.append("Permission Denial: ");
   12446                         builder.append(name);
   12447                         if (callerPackage != null) {
   12448                             builder.append(" from ");
   12449                             builder.append(callerPackage);
   12450                         }
   12451                         builder.append(" asks to run as user ");
   12452                         builder.append(userId);
   12453                         builder.append(" but is calling from user ");
   12454                         builder.append(UserHandle.getUserId(callingUid));
   12455                         builder.append("; this requires ");
   12456                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
   12457                         if (!requireFull) {
   12458                             builder.append(" or ");
   12459                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
   12460                         }
   12461                         String msg = builder.toString();
   12462                         Slog.w(TAG, msg);
   12463                         throw new SecurityException(msg);
   12464                     }
   12465                 }
   12466             }
   12467             if (userId == UserHandle.USER_CURRENT
   12468                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   12469                 // Note that we may be accessing this outside of a lock...
   12470                 // shouldn't be a big deal, if this is being called outside
   12471                 // of a locked context there is intrinsically a race with
   12472                 // the value the caller will receive and someone else changing it.
   12473                 userId = mCurrentUserId;
   12474             }
   12475             if (!allowAll && userId < 0) {
   12476                 throw new IllegalArgumentException(
   12477                         "Call does not support special user #" + userId);
   12478             }
   12479         }
   12480         return userId;
   12481     }
   12482 
   12483     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   12484             String className, int flags) {
   12485         boolean result = false;
   12486         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   12487             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
   12488                 if (ActivityManager.checkUidPermission(
   12489                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12490                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   12491                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   12492                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   12493                             + " requests FLAG_SINGLE_USER, but app does not hold "
   12494                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
   12495                     Slog.w(TAG, msg);
   12496                     throw new SecurityException(msg);
   12497                 }
   12498                 result = true;
   12499             }
   12500         } else if (componentProcessName == aInfo.packageName) {
   12501             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   12502         } else if ("system".equals(componentProcessName)) {
   12503             result = true;
   12504         }
   12505         if (DEBUG_MU) {
   12506             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   12507                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   12508         }
   12509         return result;
   12510     }
   12511 
   12512     public int bindService(IApplicationThread caller, IBinder token,
   12513             Intent service, String resolvedType,
   12514             IServiceConnection connection, int flags, int userId) {
   12515         enforceNotIsolatedCaller("bindService");
   12516         // Refuse possible leaked file descriptors
   12517         if (service != null && service.hasFileDescriptors() == true) {
   12518             throw new IllegalArgumentException("File descriptors passed in Intent");
   12519         }
   12520 
   12521         synchronized(this) {
   12522             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   12523                     connection, flags, userId);
   12524         }
   12525     }
   12526 
   12527     public boolean unbindService(IServiceConnection connection) {
   12528         synchronized (this) {
   12529             return mServices.unbindServiceLocked(connection);
   12530         }
   12531     }
   12532 
   12533     public void publishService(IBinder token, Intent intent, IBinder service) {
   12534         // Refuse possible leaked file descriptors
   12535         if (intent != null && intent.hasFileDescriptors() == true) {
   12536             throw new IllegalArgumentException("File descriptors passed in Intent");
   12537         }
   12538 
   12539         synchronized(this) {
   12540             if (!(token instanceof ServiceRecord)) {
   12541                 throw new IllegalArgumentException("Invalid service token");
   12542             }
   12543             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   12544         }
   12545     }
   12546 
   12547     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   12548         // Refuse possible leaked file descriptors
   12549         if (intent != null && intent.hasFileDescriptors() == true) {
   12550             throw new IllegalArgumentException("File descriptors passed in Intent");
   12551         }
   12552 
   12553         synchronized(this) {
   12554             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   12555         }
   12556     }
   12557 
   12558     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   12559         synchronized(this) {
   12560             if (!(token instanceof ServiceRecord)) {
   12561                 throw new IllegalArgumentException("Invalid service token");
   12562             }
   12563             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   12564         }
   12565     }
   12566 
   12567     // =========================================================
   12568     // BACKUP AND RESTORE
   12569     // =========================================================
   12570 
   12571     // Cause the target app to be launched if necessary and its backup agent
   12572     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   12573     // activity manager to announce its creation.
   12574     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   12575         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   12576         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
   12577 
   12578         synchronized(this) {
   12579             // !!! TODO: currently no check here that we're already bound
   12580             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   12581             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12582             synchronized (stats) {
   12583                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   12584             }
   12585 
   12586             // Backup agent is now in use, its package can't be stopped.
   12587             try {
   12588                 AppGlobals.getPackageManager().setPackageStoppedState(
   12589                         app.packageName, false, UserHandle.getUserId(app.uid));
   12590             } catch (RemoteException e) {
   12591             } catch (IllegalArgumentException e) {
   12592                 Slog.w(TAG, "Failed trying to unstop package "
   12593                         + app.packageName + ": " + e);
   12594             }
   12595 
   12596             BackupRecord r = new BackupRecord(ss, app, backupMode);
   12597             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   12598                     ? new ComponentName(app.packageName, app.backupAgentName)
   12599                     : new ComponentName("android", "FullBackupAgent");
   12600             // startProcessLocked() returns existing proc's record if it's already running
   12601             ProcessRecord proc = startProcessLocked(app.processName, app,
   12602                     false, 0, "backup", hostingName, false, false, false);
   12603             if (proc == null) {
   12604                 Slog.e(TAG, "Unable to start backup agent process " + r);
   12605                 return false;
   12606             }
   12607 
   12608             r.app = proc;
   12609             mBackupTarget = r;
   12610             mBackupAppName = app.packageName;
   12611 
   12612             // Try not to kill the process during backup
   12613             updateOomAdjLocked(proc);
   12614 
   12615             // If the process is already attached, schedule the creation of the backup agent now.
   12616             // If it is not yet live, this will be done when it attaches to the framework.
   12617             if (proc.thread != null) {
   12618                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   12619                 try {
   12620                     proc.thread.scheduleCreateBackupAgent(app,
   12621                             compatibilityInfoForPackageLocked(app), backupMode);
   12622                 } catch (RemoteException e) {
   12623                     // Will time out on the backup manager side
   12624                 }
   12625             } else {
   12626                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   12627             }
   12628             // Invariants: at this point, the target app process exists and the application
   12629             // is either already running or in the process of coming up.  mBackupTarget and
   12630             // mBackupAppName describe the app, so that when it binds back to the AM we
   12631             // know that it's scheduled for a backup-agent operation.
   12632         }
   12633 
   12634         return true;
   12635     }
   12636 
   12637     @Override
   12638     public void clearPendingBackup() {
   12639         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   12640         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   12641 
   12642         synchronized (this) {
   12643             mBackupTarget = null;
   12644             mBackupAppName = null;
   12645         }
   12646     }
   12647 
   12648     // A backup agent has just come up
   12649     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   12650         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   12651                 + " = " + agent);
   12652 
   12653         synchronized(this) {
   12654             if (!agentPackageName.equals(mBackupAppName)) {
   12655                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   12656                 return;
   12657             }
   12658         }
   12659 
   12660         long oldIdent = Binder.clearCallingIdentity();
   12661         try {
   12662             IBackupManager bm = IBackupManager.Stub.asInterface(
   12663                     ServiceManager.getService(Context.BACKUP_SERVICE));
   12664             bm.agentConnected(agentPackageName, agent);
   12665         } catch (RemoteException e) {
   12666             // can't happen; the backup manager service is local
   12667         } catch (Exception e) {
   12668             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   12669             e.printStackTrace();
   12670         } finally {
   12671             Binder.restoreCallingIdentity(oldIdent);
   12672         }
   12673     }
   12674 
   12675     // done with this agent
   12676     public void unbindBackupAgent(ApplicationInfo appInfo) {
   12677         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   12678         if (appInfo == null) {
   12679             Slog.w(TAG, "unbind backup agent for null app");
   12680             return;
   12681         }
   12682 
   12683         synchronized(this) {
   12684             try {
   12685                 if (mBackupAppName == null) {
   12686                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   12687                     return;
   12688                 }
   12689 
   12690                 if (!mBackupAppName.equals(appInfo.packageName)) {
   12691                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   12692                     return;
   12693                 }
   12694 
   12695                 // Not backing this app up any more; reset its OOM adjustment
   12696                 final ProcessRecord proc = mBackupTarget.app;
   12697                 updateOomAdjLocked(proc);
   12698 
   12699                 // If the app crashed during backup, 'thread' will be null here
   12700                 if (proc.thread != null) {
   12701                     try {
   12702                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   12703                                 compatibilityInfoForPackageLocked(appInfo));
   12704                     } catch (Exception e) {
   12705                         Slog.e(TAG, "Exception when unbinding backup agent:");
   12706                         e.printStackTrace();
   12707                     }
   12708                 }
   12709             } finally {
   12710                 mBackupTarget = null;
   12711                 mBackupAppName = null;
   12712             }
   12713         }
   12714     }
   12715     // =========================================================
   12716     // BROADCASTS
   12717     // =========================================================
   12718 
   12719     private final List getStickiesLocked(String action, IntentFilter filter,
   12720             List cur, int userId) {
   12721         final ContentResolver resolver = mContext.getContentResolver();
   12722         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12723         if (stickies == null) {
   12724             return cur;
   12725         }
   12726         final ArrayList<Intent> list = stickies.get(action);
   12727         if (list == null) {
   12728             return cur;
   12729         }
   12730         int N = list.size();
   12731         for (int i=0; i<N; i++) {
   12732             Intent intent = list.get(i);
   12733             if (filter.match(resolver, intent, true, TAG) >= 0) {
   12734                 if (cur == null) {
   12735                     cur = new ArrayList<Intent>();
   12736                 }
   12737                 cur.add(intent);
   12738             }
   12739         }
   12740         return cur;
   12741     }
   12742 
   12743     boolean isPendingBroadcastProcessLocked(int pid) {
   12744         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   12745                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   12746     }
   12747 
   12748     void skipPendingBroadcastLocked(int pid) {
   12749             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   12750             for (BroadcastQueue queue : mBroadcastQueues) {
   12751                 queue.skipPendingBroadcastLocked(pid);
   12752             }
   12753     }
   12754 
   12755     // The app just attached; send any pending broadcasts that it should receive
   12756     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   12757         boolean didSomething = false;
   12758         for (BroadcastQueue queue : mBroadcastQueues) {
   12759             didSomething |= queue.sendPendingBroadcastsLocked(app);
   12760         }
   12761         return didSomething;
   12762     }
   12763 
   12764     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   12765             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   12766         enforceNotIsolatedCaller("registerReceiver");
   12767         int callingUid;
   12768         int callingPid;
   12769         synchronized(this) {
   12770             ProcessRecord callerApp = null;
   12771             if (caller != null) {
   12772                 callerApp = getRecordForAppLocked(caller);
   12773                 if (callerApp == null) {
   12774                     throw new SecurityException(
   12775                             "Unable to find app for caller " + caller
   12776                             + " (pid=" + Binder.getCallingPid()
   12777                             + ") when registering receiver " + receiver);
   12778                 }
   12779                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   12780                         !callerApp.pkgList.containsKey(callerPackage)) {
   12781                     throw new SecurityException("Given caller package " + callerPackage
   12782                             + " is not running in process " + callerApp);
   12783                 }
   12784                 callingUid = callerApp.info.uid;
   12785                 callingPid = callerApp.pid;
   12786             } else {
   12787                 callerPackage = null;
   12788                 callingUid = Binder.getCallingUid();
   12789                 callingPid = Binder.getCallingPid();
   12790             }
   12791 
   12792             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   12793                     true, true, "registerReceiver", callerPackage);
   12794 
   12795             List allSticky = null;
   12796 
   12797             // Look for any matching sticky broadcasts...
   12798             Iterator actions = filter.actionsIterator();
   12799             if (actions != null) {
   12800                 while (actions.hasNext()) {
   12801                     String action = (String)actions.next();
   12802                     allSticky = getStickiesLocked(action, filter, allSticky,
   12803                             UserHandle.USER_ALL);
   12804                     allSticky = getStickiesLocked(action, filter, allSticky,
   12805                             UserHandle.getUserId(callingUid));
   12806                 }
   12807             } else {
   12808                 allSticky = getStickiesLocked(null, filter, allSticky,
   12809                         UserHandle.USER_ALL);
   12810                 allSticky = getStickiesLocked(null, filter, allSticky,
   12811                         UserHandle.getUserId(callingUid));
   12812             }
   12813 
   12814             // The first sticky in the list is returned directly back to
   12815             // the client.
   12816             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   12817 
   12818             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   12819                     + ": " + sticky);
   12820 
   12821             if (receiver == null) {
   12822                 return sticky;
   12823             }
   12824 
   12825             ReceiverList rl
   12826                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   12827             if (rl == null) {
   12828                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   12829                         userId, receiver);
   12830                 if (rl.app != null) {
   12831                     rl.app.receivers.add(rl);
   12832                 } else {
   12833                     try {
   12834                         receiver.asBinder().linkToDeath(rl, 0);
   12835                     } catch (RemoteException e) {
   12836                         return sticky;
   12837                     }
   12838                     rl.linkedToDeath = true;
   12839                 }
   12840                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   12841             } else if (rl.uid != callingUid) {
   12842                 throw new IllegalArgumentException(
   12843                         "Receiver requested to register for uid " + callingUid
   12844                         + " was previously registered for uid " + rl.uid);
   12845             } else if (rl.pid != callingPid) {
   12846                 throw new IllegalArgumentException(
   12847                         "Receiver requested to register for pid " + callingPid
   12848                         + " was previously registered for pid " + rl.pid);
   12849             } else if (rl.userId != userId) {
   12850                 throw new IllegalArgumentException(
   12851                         "Receiver requested to register for user " + userId
   12852                         + " was previously registered for user " + rl.userId);
   12853             }
   12854             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   12855                     permission, callingUid, userId);
   12856             rl.add(bf);
   12857             if (!bf.debugCheck()) {
   12858                 Slog.w(TAG, "==> For Dynamic broadast");
   12859             }
   12860             mReceiverResolver.addFilter(bf);
   12861 
   12862             // Enqueue broadcasts for all existing stickies that match
   12863             // this filter.
   12864             if (allSticky != null) {
   12865                 ArrayList receivers = new ArrayList();
   12866                 receivers.add(bf);
   12867 
   12868                 int N = allSticky.size();
   12869                 for (int i=0; i<N; i++) {
   12870                     Intent intent = (Intent)allSticky.get(i);
   12871                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   12872                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   12873                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   12874                             null, null, false, true, true, -1);
   12875                     queue.enqueueParallelBroadcastLocked(r);
   12876                     queue.scheduleBroadcastsLocked();
   12877                 }
   12878             }
   12879 
   12880             return sticky;
   12881         }
   12882     }
   12883 
   12884     public void unregisterReceiver(IIntentReceiver receiver) {
   12885         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   12886 
   12887         final long origId = Binder.clearCallingIdentity();
   12888         try {
   12889             boolean doTrim = false;
   12890 
   12891             synchronized(this) {
   12892                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   12893                 if (rl != null) {
   12894                     if (rl.curBroadcast != null) {
   12895                         BroadcastRecord r = rl.curBroadcast;
   12896                         final boolean doNext = finishReceiverLocked(
   12897                                 receiver.asBinder(), r.resultCode, r.resultData,
   12898                                 r.resultExtras, r.resultAbort);
   12899                         if (doNext) {
   12900                             doTrim = true;
   12901                             r.queue.processNextBroadcast(false);
   12902                         }
   12903                     }
   12904 
   12905                     if (rl.app != null) {
   12906                         rl.app.receivers.remove(rl);
   12907                     }
   12908                     removeReceiverLocked(rl);
   12909                     if (rl.linkedToDeath) {
   12910                         rl.linkedToDeath = false;
   12911                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   12912                     }
   12913                 }
   12914             }
   12915 
   12916             // If we actually concluded any broadcasts, we might now be able
   12917             // to trim the recipients' apps from our working set
   12918             if (doTrim) {
   12919                 trimApplications();
   12920                 return;
   12921             }
   12922 
   12923         } finally {
   12924             Binder.restoreCallingIdentity(origId);
   12925         }
   12926     }
   12927 
   12928     void removeReceiverLocked(ReceiverList rl) {
   12929         mRegisteredReceivers.remove(rl.receiver.asBinder());
   12930         int N = rl.size();
   12931         for (int i=0; i<N; i++) {
   12932             mReceiverResolver.removeFilter(rl.get(i));
   12933         }
   12934     }
   12935 
   12936     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   12937         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   12938             ProcessRecord r = mLruProcesses.get(i);
   12939             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   12940                 try {
   12941                     r.thread.dispatchPackageBroadcast(cmd, packages);
   12942                 } catch (RemoteException ex) {
   12943                 }
   12944             }
   12945         }
   12946     }
   12947 
   12948     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   12949             int[] users) {
   12950         List<ResolveInfo> receivers = null;
   12951         try {
   12952             HashSet<ComponentName> singleUserReceivers = null;
   12953             boolean scannedFirstReceivers = false;
   12954             for (int user : users) {
   12955                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   12956                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   12957                 if (user != 0 && newReceivers != null) {
   12958                     // If this is not the primary user, we need to check for
   12959                     // any receivers that should be filtered out.
   12960                     for (int i=0; i<newReceivers.size(); i++) {
   12961                         ResolveInfo ri = newReceivers.get(i);
   12962                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   12963                             newReceivers.remove(i);
   12964                             i--;
   12965                         }
   12966                     }
   12967                 }
   12968                 if (newReceivers != null && newReceivers.size() == 0) {
   12969                     newReceivers = null;
   12970                 }
   12971                 if (receivers == null) {
   12972                     receivers = newReceivers;
   12973                 } else if (newReceivers != null) {
   12974                     // We need to concatenate the additional receivers
   12975                     // found with what we have do far.  This would be easy,
   12976                     // but we also need to de-dup any receivers that are
   12977                     // singleUser.
   12978                     if (!scannedFirstReceivers) {
   12979                         // Collect any single user receivers we had already retrieved.
   12980                         scannedFirstReceivers = true;
   12981                         for (int i=0; i<receivers.size(); i++) {
   12982                             ResolveInfo ri = receivers.get(i);
   12983                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   12984                                 ComponentName cn = new ComponentName(
   12985                                         ri.activityInfo.packageName, ri.activityInfo.name);
   12986                                 if (singleUserReceivers == null) {
   12987                                     singleUserReceivers = new HashSet<ComponentName>();
   12988                                 }
   12989                                 singleUserReceivers.add(cn);
   12990                             }
   12991                         }
   12992                     }
   12993                     // Add the new results to the existing results, tracking
   12994                     // and de-dupping single user receivers.
   12995                     for (int i=0; i<newReceivers.size(); i++) {
   12996                         ResolveInfo ri = newReceivers.get(i);
   12997                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   12998                             ComponentName cn = new ComponentName(
   12999                                     ri.activityInfo.packageName, ri.activityInfo.name);
   13000                             if (singleUserReceivers == null) {
   13001                                 singleUserReceivers = new HashSet<ComponentName>();
   13002                             }
   13003                             if (!singleUserReceivers.contains(cn)) {
   13004                                 singleUserReceivers.add(cn);
   13005                                 receivers.add(ri);
   13006                             }
   13007                         } else {
   13008                             receivers.add(ri);
   13009                         }
   13010                     }
   13011                 }
   13012             }
   13013         } catch (RemoteException ex) {
   13014             // pm is in same process, this will never happen.
   13015         }
   13016         return receivers;
   13017     }
   13018 
   13019     private final int broadcastIntentLocked(ProcessRecord callerApp,
   13020             String callerPackage, Intent intent, String resolvedType,
   13021             IIntentReceiver resultTo, int resultCode, String resultData,
   13022             Bundle map, String requiredPermission, int appOp,
   13023             boolean ordered, boolean sticky, int callingPid, int callingUid,
   13024             int userId) {
   13025         intent = new Intent(intent);
   13026 
   13027         // By default broadcasts do not go to stopped apps.
   13028         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   13029 
   13030         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   13031             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   13032             + " ordered=" + ordered + " userid=" + userId);
   13033         if ((resultTo != null) && !ordered) {
   13034             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   13035         }
   13036 
   13037         userId = handleIncomingUser(callingPid, callingUid, userId,
   13038                 true, false, "broadcast", callerPackage);
   13039 
   13040         // Make sure that the user who is receiving this broadcast is started.
   13041         // If not, we will just skip it.
   13042         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   13043             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   13044                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   13045                 Slog.w(TAG, "Skipping broadcast of " + intent
   13046                         + ": user " + userId + " is stopped");
   13047                 return ActivityManager.BROADCAST_SUCCESS;
   13048             }
   13049         }
   13050 
   13051         /*
   13052          * Prevent non-system code (defined here to be non-persistent
   13053          * processes) from sending protected broadcasts.
   13054          */
   13055         int callingAppId = UserHandle.getAppId(callingUid);
   13056         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   13057             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
   13058             callingUid == 0) {
   13059             // Always okay.
   13060         } else if (callerApp == null || !callerApp.persistent) {
   13061             try {
   13062                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   13063                         intent.getAction())) {
   13064                     String msg = "Permission Denial: not allowed to send broadcast "
   13065                             + intent.getAction() + " from pid="
   13066                             + callingPid + ", uid=" + callingUid;
   13067                     Slog.w(TAG, msg);
   13068                     throw new SecurityException(msg);
   13069                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   13070                     // Special case for compatibility: we don't want apps to send this,
   13071                     // but historically it has not been protected and apps may be using it
   13072                     // to poke their own app widget.  So, instead of making it protected,
   13073                     // just limit it to the caller.
   13074                     if (callerApp == null) {
   13075                         String msg = "Permission Denial: not allowed to send broadcast "
   13076                                 + intent.getAction() + " from unknown caller.";
   13077                         Slog.w(TAG, msg);
   13078                         throw new SecurityException(msg);
   13079                     } else if (intent.getComponent() != null) {
   13080                         // They are good enough to send to an explicit component...  verify
   13081                         // it is being sent to the calling app.
   13082                         if (!intent.getComponent().getPackageName().equals(
   13083                                 callerApp.info.packageName)) {
   13084                             String msg = "Permission Denial: not allowed to send broadcast "
   13085                                     + intent.getAction() + " to "
   13086                                     + intent.getComponent().getPackageName() + " from "
   13087                                     + callerApp.info.packageName;
   13088                             Slog.w(TAG, msg);
   13089                             throw new SecurityException(msg);
   13090                         }
   13091                     } else {
   13092                         // Limit broadcast to their own package.
   13093                         intent.setPackage(callerApp.info.packageName);
   13094                     }
   13095                 }
   13096             } catch (RemoteException e) {
   13097                 Slog.w(TAG, "Remote exception", e);
   13098                 return ActivityManager.BROADCAST_SUCCESS;
   13099             }
   13100         }
   13101 
   13102         // Handle special intents: if this broadcast is from the package
   13103         // manager about a package being removed, we need to remove all of
   13104         // its activities from the history stack.
   13105         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   13106                 intent.getAction());
   13107         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   13108                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   13109                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   13110                 || uidRemoved) {
   13111             if (checkComponentPermission(
   13112                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   13113                     callingPid, callingUid, -1, true)
   13114                     == PackageManager.PERMISSION_GRANTED) {
   13115                 if (uidRemoved) {
   13116                     final Bundle intentExtras = intent.getExtras();
   13117                     final int uid = intentExtras != null
   13118                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   13119                     if (uid >= 0) {
   13120                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   13121                         synchronized (bs) {
   13122                             bs.removeUidStatsLocked(uid);
   13123                         }
   13124                         mAppOpsService.uidRemoved(uid);
   13125                     }
   13126                 } else {
   13127                     // If resources are unavailable just force stop all
   13128                     // those packages and flush the attribute cache as well.
   13129                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   13130                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13131                         if (list != null && (list.length > 0)) {
   13132                             for (String pkg : list) {
   13133                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
   13134                                         "storage unmount");
   13135                             }
   13136                             sendPackageBroadcastLocked(
   13137                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   13138                         }
   13139                     } else {
   13140                         Uri data = intent.getData();
   13141                         String ssp;
   13142                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13143                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
   13144                                     intent.getAction());
   13145                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   13146                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
   13147                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
   13148                                         false, userId, removed ? "pkg removed" : "pkg changed");
   13149                             }
   13150                             if (removed) {
   13151                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   13152                                         new String[] {ssp}, userId);
   13153                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
   13154                                     mAppOpsService.packageRemoved(
   13155                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   13156 
   13157                                     // Remove all permissions granted from/to this package
   13158                                     removeUriPermissionsForPackageLocked(ssp, userId, true);
   13159                                 }
   13160                             }
   13161                         }
   13162                     }
   13163                 }
   13164             } else {
   13165                 String msg = "Permission Denial: " + intent.getAction()
   13166                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   13167                         + ", uid=" + callingUid + ")"
   13168                         + " requires "
   13169                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   13170                 Slog.w(TAG, msg);
   13171                 throw new SecurityException(msg);
   13172             }
   13173 
   13174         // Special case for adding a package: by default turn on compatibility
   13175         // mode.
   13176         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   13177             Uri data = intent.getData();
   13178             String ssp;
   13179             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13180                 mCompatModePackages.handlePackageAddedLocked(ssp,
   13181                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   13182             }
   13183         }
   13184 
   13185         /*
   13186          * If this is the time zone changed action, queue up a message that will reset the timezone
   13187          * of all currently running processes. This message will get queued up before the broadcast
   13188          * happens.
   13189          */
   13190         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   13191             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   13192         }
   13193 
   13194         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   13195             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   13196         }
   13197 
   13198         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   13199             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   13200             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   13201         }
   13202 
   13203         // Add to the sticky list if requested.
   13204         if (sticky) {
   13205             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   13206                     callingPid, callingUid)
   13207                     != PackageManager.PERMISSION_GRANTED) {
   13208                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   13209                         + callingPid + ", uid=" + callingUid
   13210                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13211                 Slog.w(TAG, msg);
   13212                 throw new SecurityException(msg);
   13213             }
   13214             if (requiredPermission != null) {
   13215                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   13216                         + " and enforce permission " + requiredPermission);
   13217                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   13218             }
   13219             if (intent.getComponent() != null) {
   13220                 throw new SecurityException(
   13221                         "Sticky broadcasts can't target a specific component");
   13222             }
   13223             // We use userId directly here, since the "all" target is maintained
   13224             // as a separate set of sticky broadcasts.
   13225             if (userId != UserHandle.USER_ALL) {
   13226                 // But first, if this is not a broadcast to all users, then
   13227                 // make sure it doesn't conflict with an existing broadcast to
   13228                 // all users.
   13229                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   13230                         UserHandle.USER_ALL);
   13231                 if (stickies != null) {
   13232                     ArrayList<Intent> list = stickies.get(intent.getAction());
   13233                     if (list != null) {
   13234                         int N = list.size();
   13235                         int i;
   13236                         for (i=0; i<N; i++) {
   13237                             if (intent.filterEquals(list.get(i))) {
   13238                                 throw new IllegalArgumentException(
   13239                                         "Sticky broadcast " + intent + " for user "
   13240                                         + userId + " conflicts with existing global broadcast");
   13241                             }
   13242                         }
   13243                     }
   13244                 }
   13245             }
   13246             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13247             if (stickies == null) {
   13248                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   13249                 mStickyBroadcasts.put(userId, stickies);
   13250             }
   13251             ArrayList<Intent> list = stickies.get(intent.getAction());
   13252             if (list == null) {
   13253                 list = new ArrayList<Intent>();
   13254                 stickies.put(intent.getAction(), list);
   13255             }
   13256             int N = list.size();
   13257             int i;
   13258             for (i=0; i<N; i++) {
   13259                 if (intent.filterEquals(list.get(i))) {
   13260                     // This sticky already exists, replace it.
   13261                     list.set(i, new Intent(intent));
   13262                     break;
   13263                 }
   13264             }
   13265             if (i >= N) {
   13266                 list.add(new Intent(intent));
   13267             }
   13268         }
   13269 
   13270         int[] users;
   13271         if (userId == UserHandle.USER_ALL) {
   13272             // Caller wants broadcast to go to all started users.
   13273             users = mStartedUserArray;
   13274         } else {
   13275             // Caller wants broadcast to go to one specific user.
   13276             users = new int[] {userId};
   13277         }
   13278 
   13279         // Figure out who all will receive this broadcast.
   13280         List receivers = null;
   13281         List<BroadcastFilter> registeredReceivers = null;
   13282         // Need to resolve the intent to interested receivers...
   13283         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   13284                  == 0) {
   13285             receivers = collectReceiverComponents(intent, resolvedType, users);
   13286         }
   13287         if (intent.getComponent() == null) {
   13288             registeredReceivers = mReceiverResolver.queryIntent(intent,
   13289                     resolvedType, false, userId);
   13290         }
   13291 
   13292         final boolean replacePending =
   13293                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   13294 
   13295         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   13296                 + " replacePending=" + replacePending);
   13297 
   13298         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   13299         if (!ordered && NR > 0) {
   13300             // If we are not serializing this broadcast, then send the
   13301             // registered receivers separately so they don't wait for the
   13302             // components to be launched.
   13303             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   13304             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13305                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   13306                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   13307                     ordered, sticky, false, userId);
   13308             if (DEBUG_BROADCAST) Slog.v(
   13309                     TAG, "Enqueueing parallel broadcast " + r);
   13310             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   13311             if (!replaced) {
   13312                 queue.enqueueParallelBroadcastLocked(r);
   13313                 queue.scheduleBroadcastsLocked();
   13314             }
   13315             registeredReceivers = null;
   13316             NR = 0;
   13317         }
   13318 
   13319         // Merge into one list.
   13320         int ir = 0;
   13321         if (receivers != null) {
   13322             // A special case for PACKAGE_ADDED: do not allow the package
   13323             // being added to see this broadcast.  This prevents them from
   13324             // using this as a back door to get run as soon as they are
   13325             // installed.  Maybe in the future we want to have a special install
   13326             // broadcast or such for apps, but we'd like to deliberately make
   13327             // this decision.
   13328             String skipPackages[] = null;
   13329             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   13330                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   13331                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   13332                 Uri data = intent.getData();
   13333                 if (data != null) {
   13334                     String pkgName = data.getSchemeSpecificPart();
   13335                     if (pkgName != null) {
   13336                         skipPackages = new String[] { pkgName };
   13337                     }
   13338                 }
   13339             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   13340                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13341             }
   13342             if (skipPackages != null && (skipPackages.length > 0)) {
   13343                 for (String skipPackage : skipPackages) {
   13344                     if (skipPackage != null) {
   13345                         int NT = receivers.size();
   13346                         for (int it=0; it<NT; it++) {
   13347                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   13348                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   13349                                 receivers.remove(it);
   13350                                 it--;
   13351                                 NT--;
   13352                             }
   13353                         }
   13354                     }
   13355                 }
   13356             }
   13357 
   13358             int NT = receivers != null ? receivers.size() : 0;
   13359             int it = 0;
   13360             ResolveInfo curt = null;
   13361             BroadcastFilter curr = null;
   13362             while (it < NT && ir < NR) {
   13363                 if (curt == null) {
   13364                     curt = (ResolveInfo)receivers.get(it);
   13365                 }
   13366                 if (curr == null) {
   13367                     curr = registeredReceivers.get(ir);
   13368                 }
   13369                 if (curr.getPriority() >= curt.priority) {
   13370                     // Insert this broadcast record into the final list.
   13371                     receivers.add(it, curr);
   13372                     ir++;
   13373                     curr = null;
   13374                     it++;
   13375                     NT++;
   13376                 } else {
   13377                     // Skip to the next ResolveInfo in the final list.
   13378                     it++;
   13379                     curt = null;
   13380                 }
   13381             }
   13382         }
   13383         while (ir < NR) {
   13384             if (receivers == null) {
   13385                 receivers = new ArrayList();
   13386             }
   13387             receivers.add(registeredReceivers.get(ir));
   13388             ir++;
   13389         }
   13390 
   13391         if ((receivers != null && receivers.size() > 0)
   13392                 || resultTo != null) {
   13393             BroadcastQueue queue = broadcastQueueForIntent(intent);
   13394             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13395                     callerPackage, callingPid, callingUid, resolvedType,
   13396                     requiredPermission, appOp, receivers, resultTo, resultCode,
   13397                     resultData, map, ordered, sticky, false, userId);
   13398             if (DEBUG_BROADCAST) Slog.v(
   13399                     TAG, "Enqueueing ordered broadcast " + r
   13400                     + ": prev had " + queue.mOrderedBroadcasts.size());
   13401             if (DEBUG_BROADCAST) {
   13402                 int seq = r.intent.getIntExtra("seq", -1);
   13403                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   13404             }
   13405             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   13406             if (!replaced) {
   13407                 queue.enqueueOrderedBroadcastLocked(r);
   13408                 queue.scheduleBroadcastsLocked();
   13409             }
   13410         }
   13411 
   13412         return ActivityManager.BROADCAST_SUCCESS;
   13413     }
   13414 
   13415     final Intent verifyBroadcastLocked(Intent intent) {
   13416         // Refuse possible leaked file descriptors
   13417         if (intent != null && intent.hasFileDescriptors() == true) {
   13418             throw new IllegalArgumentException("File descriptors passed in Intent");
   13419         }
   13420 
   13421         int flags = intent.getFlags();
   13422 
   13423         if (!mProcessesReady) {
   13424             // if the caller really truly claims to know what they're doing, go
   13425             // ahead and allow the broadcast without launching any receivers
   13426             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   13427                 intent = new Intent(intent);
   13428                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13429             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   13430                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   13431                         + " before boot completion");
   13432                 throw new IllegalStateException("Cannot broadcast before boot completed");
   13433             }
   13434         }
   13435 
   13436         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   13437             throw new IllegalArgumentException(
   13438                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   13439         }
   13440 
   13441         return intent;
   13442     }
   13443 
   13444     public final int broadcastIntent(IApplicationThread caller,
   13445             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13446             int resultCode, String resultData, Bundle map,
   13447             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   13448         enforceNotIsolatedCaller("broadcastIntent");
   13449         synchronized(this) {
   13450             intent = verifyBroadcastLocked(intent);
   13451 
   13452             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   13453             final int callingPid = Binder.getCallingPid();
   13454             final int callingUid = Binder.getCallingUid();
   13455             final long origId = Binder.clearCallingIdentity();
   13456             int res = broadcastIntentLocked(callerApp,
   13457                     callerApp != null ? callerApp.info.packageName : null,
   13458                     intent, resolvedType, resultTo,
   13459                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   13460                     callingPid, callingUid, userId);
   13461             Binder.restoreCallingIdentity(origId);
   13462             return res;
   13463         }
   13464     }
   13465 
   13466     int broadcastIntentInPackage(String packageName, int uid,
   13467             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13468             int resultCode, String resultData, Bundle map,
   13469             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   13470         synchronized(this) {
   13471             intent = verifyBroadcastLocked(intent);
   13472 
   13473             final long origId = Binder.clearCallingIdentity();
   13474             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   13475                     resultTo, resultCode, resultData, map, requiredPermission,
   13476                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   13477             Binder.restoreCallingIdentity(origId);
   13478             return res;
   13479         }
   13480     }
   13481 
   13482     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   13483         // Refuse possible leaked file descriptors
   13484         if (intent != null && intent.hasFileDescriptors() == true) {
   13485             throw new IllegalArgumentException("File descriptors passed in Intent");
   13486         }
   13487 
   13488         userId = handleIncomingUser(Binder.getCallingPid(),
   13489                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
   13490 
   13491         synchronized(this) {
   13492             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   13493                     != PackageManager.PERMISSION_GRANTED) {
   13494                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   13495                         + Binder.getCallingPid()
   13496                         + ", uid=" + Binder.getCallingUid()
   13497                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13498                 Slog.w(TAG, msg);
   13499                 throw new SecurityException(msg);
   13500             }
   13501             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13502             if (stickies != null) {
   13503                 ArrayList<Intent> list = stickies.get(intent.getAction());
   13504                 if (list != null) {
   13505                     int N = list.size();
   13506                     int i;
   13507                     for (i=0; i<N; i++) {
   13508                         if (intent.filterEquals(list.get(i))) {
   13509                             list.remove(i);
   13510                             break;
   13511                         }
   13512                     }
   13513                     if (list.size() <= 0) {
   13514                         stickies.remove(intent.getAction());
   13515                     }
   13516                 }
   13517                 if (stickies.size() <= 0) {
   13518                     mStickyBroadcasts.remove(userId);
   13519                 }
   13520             }
   13521         }
   13522     }
   13523 
   13524     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   13525             String resultData, Bundle resultExtras, boolean resultAbort) {
   13526         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   13527         if (r == null) {
   13528             Slog.w(TAG, "finishReceiver called but not found on queue");
   13529             return false;
   13530         }
   13531 
   13532         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   13533     }
   13534 
   13535     void backgroundServicesFinishedLocked(int userId) {
   13536         for (BroadcastQueue queue : mBroadcastQueues) {
   13537             queue.backgroundServicesFinishedLocked(userId);
   13538         }
   13539     }
   13540 
   13541     public void finishReceiver(IBinder who, int resultCode, String resultData,
   13542             Bundle resultExtras, boolean resultAbort) {
   13543         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   13544 
   13545         // Refuse possible leaked file descriptors
   13546         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   13547             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13548         }
   13549 
   13550         final long origId = Binder.clearCallingIdentity();
   13551         try {
   13552             boolean doNext = false;
   13553             BroadcastRecord r;
   13554 
   13555             synchronized(this) {
   13556                 r = broadcastRecordForReceiverLocked(who);
   13557                 if (r != null) {
   13558                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   13559                         resultData, resultExtras, resultAbort, true);
   13560                 }
   13561             }
   13562 
   13563             if (doNext) {
   13564                 r.queue.processNextBroadcast(false);
   13565             }
   13566             trimApplications();
   13567         } finally {
   13568             Binder.restoreCallingIdentity(origId);
   13569         }
   13570     }
   13571 
   13572     // =========================================================
   13573     // INSTRUMENTATION
   13574     // =========================================================
   13575 
   13576     public boolean startInstrumentation(ComponentName className,
   13577             String profileFile, int flags, Bundle arguments,
   13578             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   13579             int userId) {
   13580         enforceNotIsolatedCaller("startInstrumentation");
   13581         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   13582                 userId, false, true, "startInstrumentation", null);
   13583         // Refuse possible leaked file descriptors
   13584         if (arguments != null && arguments.hasFileDescriptors()) {
   13585             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13586         }
   13587 
   13588         synchronized(this) {
   13589             InstrumentationInfo ii = null;
   13590             ApplicationInfo ai = null;
   13591             try {
   13592                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13593                     className, STOCK_PM_FLAGS);
   13594                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   13595                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   13596             } catch (PackageManager.NameNotFoundException e) {
   13597             } catch (RemoteException e) {
   13598             }
   13599             if (ii == null) {
   13600                 reportStartInstrumentationFailure(watcher, className,
   13601                         "Unable to find instrumentation info for: " + className);
   13602                 return false;
   13603             }
   13604             if (ai == null) {
   13605                 reportStartInstrumentationFailure(watcher, className,
   13606                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13607                 return false;
   13608             }
   13609 
   13610             int match = mContext.getPackageManager().checkSignatures(
   13611                     ii.targetPackage, ii.packageName);
   13612             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13613                 String msg = "Permission Denial: starting instrumentation "
   13614                         + className + " from pid="
   13615                         + Binder.getCallingPid()
   13616                         + ", uid=" + Binder.getCallingPid()
   13617                         + " not allowed because package " + ii.packageName
   13618                         + " does not have a signature matching the target "
   13619                         + ii.targetPackage;
   13620                 reportStartInstrumentationFailure(watcher, className, msg);
   13621                 throw new SecurityException(msg);
   13622             }
   13623 
   13624             final long origId = Binder.clearCallingIdentity();
   13625             // Instrumentation can kill and relaunch even persistent processes
   13626             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
   13627                     "start instr");
   13628             ProcessRecord app = addAppLocked(ai, false);
   13629             app.instrumentationClass = className;
   13630             app.instrumentationInfo = ai;
   13631             app.instrumentationProfileFile = profileFile;
   13632             app.instrumentationArguments = arguments;
   13633             app.instrumentationWatcher = watcher;
   13634             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   13635             app.instrumentationResultClass = className;
   13636             Binder.restoreCallingIdentity(origId);
   13637         }
   13638 
   13639         return true;
   13640     }
   13641 
   13642     /**
   13643      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13644      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13645      * the "am" command to report errors with more information.
   13646      *
   13647      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13648      * @param cn The component name of the instrumentation.
   13649      * @param report The error report.
   13650      */
   13651     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13652             ComponentName cn, String report) {
   13653         Slog.w(TAG, report);
   13654         try {
   13655             if (watcher != null) {
   13656                 Bundle results = new Bundle();
   13657                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13658                 results.putString("Error", report);
   13659                 watcher.instrumentationStatus(cn, -1, results);
   13660             }
   13661         } catch (RemoteException e) {
   13662             Slog.w(TAG, e);
   13663         }
   13664     }
   13665 
   13666     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13667         if (app.instrumentationWatcher != null) {
   13668             try {
   13669                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13670                 app.instrumentationWatcher.instrumentationFinished(
   13671                     app.instrumentationClass,
   13672                     resultCode,
   13673                     results);
   13674             } catch (RemoteException e) {
   13675             }
   13676         }
   13677         if (app.instrumentationUiAutomationConnection != null) {
   13678             try {
   13679                 app.instrumentationUiAutomationConnection.shutdown();
   13680             } catch (RemoteException re) {
   13681                 /* ignore */
   13682             }
   13683             // Only a UiAutomation can set this flag and now that
   13684             // it is finished we make sure it is reset to its default.
   13685             mUserIsMonkey = false;
   13686         }
   13687         app.instrumentationWatcher = null;
   13688         app.instrumentationUiAutomationConnection = null;
   13689         app.instrumentationClass = null;
   13690         app.instrumentationInfo = null;
   13691         app.instrumentationProfileFile = null;
   13692         app.instrumentationArguments = null;
   13693 
   13694         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
   13695                 "finished inst");
   13696     }
   13697 
   13698     public void finishInstrumentation(IApplicationThread target,
   13699             int resultCode, Bundle results) {
   13700         int userId = UserHandle.getCallingUserId();
   13701         // Refuse possible leaked file descriptors
   13702         if (results != null && results.hasFileDescriptors()) {
   13703             throw new IllegalArgumentException("File descriptors passed in Intent");
   13704         }
   13705 
   13706         synchronized(this) {
   13707             ProcessRecord app = getRecordForAppLocked(target);
   13708             if (app == null) {
   13709                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13710                 return;
   13711             }
   13712             final long origId = Binder.clearCallingIdentity();
   13713             finishInstrumentationLocked(app, resultCode, results);
   13714             Binder.restoreCallingIdentity(origId);
   13715         }
   13716     }
   13717 
   13718     // =========================================================
   13719     // CONFIGURATION
   13720     // =========================================================
   13721 
   13722     public ConfigurationInfo getDeviceConfigurationInfo() {
   13723         ConfigurationInfo config = new ConfigurationInfo();
   13724         synchronized (this) {
   13725             config.reqTouchScreen = mConfiguration.touchscreen;
   13726             config.reqKeyboardType = mConfiguration.keyboard;
   13727             config.reqNavigation = mConfiguration.navigation;
   13728             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13729                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13730                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13731             }
   13732             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13733                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13734                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13735             }
   13736             config.reqGlEsVersion = GL_ES_VERSION;
   13737         }
   13738         return config;
   13739     }
   13740 
   13741     ActivityStack getFocusedStack() {
   13742         return mStackSupervisor.getFocusedStack();
   13743     }
   13744 
   13745     public Configuration getConfiguration() {
   13746         Configuration ci;
   13747         synchronized(this) {
   13748             ci = new Configuration(mConfiguration);
   13749         }
   13750         return ci;
   13751     }
   13752 
   13753     public void updatePersistentConfiguration(Configuration values) {
   13754         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13755                 "updateConfiguration()");
   13756         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   13757                 "updateConfiguration()");
   13758         if (values == null) {
   13759             throw new NullPointerException("Configuration must not be null");
   13760         }
   13761 
   13762         synchronized(this) {
   13763             final long origId = Binder.clearCallingIdentity();
   13764             updateConfigurationLocked(values, null, true, false);
   13765             Binder.restoreCallingIdentity(origId);
   13766         }
   13767     }
   13768 
   13769     public void updateConfiguration(Configuration values) {
   13770         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13771                 "updateConfiguration()");
   13772 
   13773         synchronized(this) {
   13774             if (values == null && mWindowManager != null) {
   13775                 // sentinel: fetch the current configuration from the window manager
   13776                 values = mWindowManager.computeNewConfiguration();
   13777             }
   13778 
   13779             if (mWindowManager != null) {
   13780                 mProcessList.applyDisplaySize(mWindowManager);
   13781             }
   13782 
   13783             final long origId = Binder.clearCallingIdentity();
   13784             if (values != null) {
   13785                 Settings.System.clearConfiguration(values);
   13786             }
   13787             updateConfigurationLocked(values, null, false, false);
   13788             Binder.restoreCallingIdentity(origId);
   13789         }
   13790     }
   13791 
   13792     /**
   13793      * Do either or both things: (1) change the current configuration, and (2)
   13794      * make sure the given activity is running with the (now) current
   13795      * configuration.  Returns true if the activity has been left running, or
   13796      * false if <var>starting</var> is being destroyed to match the new
   13797      * configuration.
   13798      * @param persistent TODO
   13799      */
   13800     boolean updateConfigurationLocked(Configuration values,
   13801             ActivityRecord starting, boolean persistent, boolean initLocale) {
   13802         // do nothing if we are headless
   13803         if (mHeadless) return true;
   13804 
   13805         int changes = 0;
   13806 
   13807         if (values != null) {
   13808             Configuration newConfig = new Configuration(mConfiguration);
   13809             changes = newConfig.updateFrom(values);
   13810             if (changes != 0) {
   13811                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   13812                     Slog.i(TAG, "Updating configuration to: " + values);
   13813                 }
   13814 
   13815                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   13816 
   13817                 if (values.locale != null && !initLocale) {
   13818                     saveLocaleLocked(values.locale,
   13819                                      !values.locale.equals(mConfiguration.locale),
   13820                                      values.userSetLocale);
   13821                 }
   13822 
   13823                 mConfigurationSeq++;
   13824                 if (mConfigurationSeq <= 0) {
   13825                     mConfigurationSeq = 1;
   13826                 }
   13827                 newConfig.seq = mConfigurationSeq;
   13828                 mConfiguration = newConfig;
   13829                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   13830 
   13831                 final Configuration configCopy = new Configuration(mConfiguration);
   13832 
   13833                 // TODO: If our config changes, should we auto dismiss any currently
   13834                 // showing dialogs?
   13835                 mShowDialogs = shouldShowDialogs(newConfig);
   13836 
   13837                 AttributeCache ac = AttributeCache.instance();
   13838                 if (ac != null) {
   13839                     ac.updateConfiguration(configCopy);
   13840                 }
   13841 
   13842                 // Make sure all resources in our process are updated
   13843                 // right now, so that anyone who is going to retrieve
   13844                 // resource values after we return will be sure to get
   13845                 // the new ones.  This is especially important during
   13846                 // boot, where the first config change needs to guarantee
   13847                 // all resources have that config before following boot
   13848                 // code is executed.
   13849                 mSystemThread.applyConfigurationToResources(configCopy);
   13850 
   13851                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   13852                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   13853                     msg.obj = new Configuration(configCopy);
   13854                     mHandler.sendMessage(msg);
   13855                 }
   13856 
   13857                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   13858                     ProcessRecord app = mLruProcesses.get(i);
   13859                     try {
   13860                         if (app.thread != null) {
   13861                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   13862                                     + app.processName + " new config " + mConfiguration);
   13863                             app.thread.scheduleConfigurationChanged(configCopy);
   13864                         }
   13865                     } catch (Exception e) {
   13866                     }
   13867                 }
   13868                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   13869                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   13870                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   13871                         | Intent.FLAG_RECEIVER_FOREGROUND);
   13872                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   13873                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   13874                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   13875                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   13876                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   13877                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   13878                     broadcastIntentLocked(null, null, intent,
   13879                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   13880                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   13881                 }
   13882             }
   13883         }
   13884 
   13885         boolean kept = true;
   13886         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   13887         if (changes != 0 && starting == null) {
   13888             // If the configuration changed, and the caller is not already
   13889             // in the process of starting an activity, then find the top
   13890             // activity to check if its configuration needs to change.
   13891             starting = mainStack.topRunningActivityLocked(null);
   13892         }
   13893 
   13894         if (starting != null) {
   13895             kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   13896             // And we need to make sure at this point that all other activities
   13897             // are made visible with the correct configuration.
   13898             mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   13899         }
   13900 
   13901         if (values != null && mWindowManager != null) {
   13902             mWindowManager.setNewConfiguration(mConfiguration);
   13903         }
   13904 
   13905         return kept;
   13906     }
   13907 
   13908     /**
   13909      * Decide based on the configuration whether we should shouw the ANR,
   13910      * crash, etc dialogs.  The idea is that if there is no affordnace to
   13911      * press the on-screen buttons, we shouldn't show the dialog.
   13912      *
   13913      * A thought: SystemUI might also want to get told about this, the Power
   13914      * dialog / global actions also might want different behaviors.
   13915      */
   13916     private static final boolean shouldShowDialogs(Configuration config) {
   13917         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   13918                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   13919     }
   13920 
   13921     /**
   13922      * Save the locale.  You must be inside a synchronized (this) block.
   13923      */
   13924     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   13925         if(isDiff) {
   13926             SystemProperties.set("user.language", l.getLanguage());
   13927             SystemProperties.set("user.region", l.getCountry());
   13928         }
   13929 
   13930         if(isPersist) {
   13931             SystemProperties.set("persist.sys.language", l.getLanguage());
   13932             SystemProperties.set("persist.sys.country", l.getCountry());
   13933             SystemProperties.set("persist.sys.localevar", l.getVariant());
   13934         }
   13935     }
   13936 
   13937     @Override
   13938     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   13939         ActivityRecord srec = ActivityRecord.forToken(token);
   13940         return srec != null && srec.task.affinity != null &&
   13941                 srec.task.affinity.equals(destAffinity);
   13942     }
   13943 
   13944     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   13945             Intent resultData) {
   13946 
   13947         synchronized (this) {
   13948             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   13949             if (stack != null) {
   13950                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   13951             }
   13952             return false;
   13953         }
   13954     }
   13955 
   13956     public int getLaunchedFromUid(IBinder activityToken) {
   13957         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   13958         if (srec == null) {
   13959             return -1;
   13960         }
   13961         return srec.launchedFromUid;
   13962     }
   13963 
   13964     public String getLaunchedFromPackage(IBinder activityToken) {
   13965         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   13966         if (srec == null) {
   13967             return null;
   13968         }
   13969         return srec.launchedFromPackage;
   13970     }
   13971 
   13972     // =========================================================
   13973     // LIFETIME MANAGEMENT
   13974     // =========================================================
   13975 
   13976     // Returns which broadcast queue the app is the current [or imminent] receiver
   13977     // on, or 'null' if the app is not an active broadcast recipient.
   13978     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   13979         BroadcastRecord r = app.curReceiver;
   13980         if (r != null) {
   13981             return r.queue;
   13982         }
   13983 
   13984         // It's not the current receiver, but it might be starting up to become one
   13985         synchronized (this) {
   13986             for (BroadcastQueue queue : mBroadcastQueues) {
   13987                 r = queue.mPendingBroadcast;
   13988                 if (r != null && r.curApp == app) {
   13989                     // found it; report which queue it's in
   13990                     return queue;
   13991                 }
   13992             }
   13993         }
   13994 
   13995         return null;
   13996     }
   13997 
   13998     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   13999             boolean doingAll, long now) {
   14000         if (mAdjSeq == app.adjSeq) {
   14001             // This adjustment has already been computed.
   14002             return app.curRawAdj;
   14003         }
   14004 
   14005         if (app.thread == null) {
   14006             app.adjSeq = mAdjSeq;
   14007             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14008             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14009             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   14010         }
   14011 
   14012         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   14013         app.adjSource = null;
   14014         app.adjTarget = null;
   14015         app.empty = false;
   14016         app.cached = false;
   14017         app.hasClientActivities = false;
   14018 
   14019         final int activitiesSize = app.activities.size();
   14020 
   14021         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14022             // The max adjustment doesn't allow this app to be anything
   14023             // below foreground, so it is not worth doing work for it.
   14024             app.adjType = "fixed";
   14025             app.adjSeq = mAdjSeq;
   14026             app.curRawAdj = app.maxAdj;
   14027             app.hasActivities = false;
   14028             app.foregroundActivities = false;
   14029             app.keeping = true;
   14030             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   14031             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   14032             // System process can do UI, and when they do we want to have
   14033             // them trim their memory after the user leaves the UI.  To
   14034             // facilitate this, here we need to determine whether or not it
   14035             // is currently showing UI.
   14036             app.systemNoUi = true;
   14037             if (app == TOP_APP) {
   14038                 app.systemNoUi = false;
   14039                 app.hasActivities = true;
   14040             } else if (activitiesSize > 0) {
   14041                 for (int j = 0; j < activitiesSize; j++) {
   14042                     final ActivityRecord r = app.activities.get(j);
   14043                     if (r.visible) {
   14044                         app.systemNoUi = false;
   14045                     }
   14046                     if (r.app == app) {
   14047                         app.hasActivities = true;
   14048                     }
   14049                 }
   14050             }
   14051             if (!app.systemNoUi) {
   14052                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   14053             }
   14054             return (app.curAdj=app.maxAdj);
   14055         }
   14056 
   14057         app.keeping = false;
   14058         app.systemNoUi = false;
   14059         app.hasActivities = false;
   14060 
   14061         // Determine the importance of the process, starting with most
   14062         // important to least, and assign an appropriate OOM adjustment.
   14063         int adj;
   14064         int schedGroup;
   14065         int procState;
   14066         boolean foregroundActivities = false;
   14067         boolean interesting = false;
   14068         BroadcastQueue queue;
   14069         if (app == TOP_APP) {
   14070             // The last app on the list is the foreground app.
   14071             adj = ProcessList.FOREGROUND_APP_ADJ;
   14072             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14073             app.adjType = "top-activity";
   14074             foregroundActivities = true;
   14075             interesting = true;
   14076             app.hasActivities = true;
   14077             procState = ActivityManager.PROCESS_STATE_TOP;
   14078         } else if (app.instrumentationClass != null) {
   14079             // Don't want to kill running instrumentation.
   14080             adj = ProcessList.FOREGROUND_APP_ADJ;
   14081             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14082             app.adjType = "instrumentation";
   14083             interesting = true;
   14084             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14085         } else if ((queue = isReceivingBroadcast(app)) != null) {
   14086             // An app that is currently receiving a broadcast also
   14087             // counts as being in the foreground for OOM killer purposes.
   14088             // It's placed in a sched group based on the nature of the
   14089             // broadcast as reflected by which queue it's active in.
   14090             adj = ProcessList.FOREGROUND_APP_ADJ;
   14091             schedGroup = (queue == mFgBroadcastQueue)
   14092                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14093             app.adjType = "broadcast";
   14094             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   14095         } else if (app.executingServices.size() > 0) {
   14096             // An app that is currently executing a service callback also
   14097             // counts as being in the foreground.
   14098             adj = ProcessList.FOREGROUND_APP_ADJ;
   14099             schedGroup = app.execServicesFg ?
   14100                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14101             app.adjType = "exec-service";
   14102             procState = ActivityManager.PROCESS_STATE_SERVICE;
   14103             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   14104         } else {
   14105             // As far as we know the process is empty.  We may change our mind later.
   14106             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14107             // At this point we don't actually know the adjustment.  Use the cached adj
   14108             // value that the caller wants us to.
   14109             adj = cachedAdj;
   14110             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14111             app.cached = true;
   14112             app.empty = true;
   14113             app.adjType = "cch-empty";
   14114         }
   14115 
   14116         // Examine all activities if not already foreground.
   14117         if (!foregroundActivities && activitiesSize > 0) {
   14118             for (int j = 0; j < activitiesSize; j++) {
   14119                 final ActivityRecord r = app.activities.get(j);
   14120                 if (r.app != app) {
   14121                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   14122                             + app + "?!?");
   14123                     continue;
   14124                 }
   14125                 app.hasActivities = true;
   14126                 if (r.visible) {
   14127                     // App has a visible activity; only upgrade adjustment.
   14128                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14129                         adj = ProcessList.VISIBLE_APP_ADJ;
   14130                         app.adjType = "visible";
   14131                     }
   14132                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14133                         procState = ActivityManager.PROCESS_STATE_TOP;
   14134                     }
   14135                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14136                     app.cached = false;
   14137                     app.empty = false;
   14138                     foregroundActivities = true;
   14139                     break;
   14140                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   14141                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14142                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14143                         app.adjType = "pausing";
   14144                     }
   14145                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14146                         procState = ActivityManager.PROCESS_STATE_TOP;
   14147                     }
   14148                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14149                     app.cached = false;
   14150                     app.empty = false;
   14151                     foregroundActivities = true;
   14152                 } else if (r.state == ActivityState.STOPPING) {
   14153                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14154                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14155                         app.adjType = "stopping";
   14156                     }
   14157                     // For the process state, we will at this point consider the
   14158                     // process to be cached.  It will be cached either as an activity
   14159                     // or empty depending on whether the activity is finishing.  We do
   14160                     // this so that we can treat the process as cached for purposes of
   14161                     // memory trimming (determing current memory level, trim command to
   14162                     // send to process) since there can be an arbitrary number of stopping
   14163                     // processes and they should soon all go into the cached state.
   14164                     if (!r.finishing) {
   14165                         if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14166                             procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14167                         }
   14168                     }
   14169                     app.cached = false;
   14170                     app.empty = false;
   14171                     foregroundActivities = true;
   14172                 } else {
   14173                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14174                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14175                         app.adjType = "cch-act";
   14176                     }
   14177                 }
   14178             }
   14179         }
   14180 
   14181         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14182             if (app.foregroundServices) {
   14183                 // The user is aware of this app, so make it visible.
   14184                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14185                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14186                 app.cached = false;
   14187                 app.adjType = "fg-service";
   14188                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14189             } else if (app.forcingToForeground != null) {
   14190                 // The user is aware of this app, so make it visible.
   14191                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14192                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14193                 app.cached = false;
   14194                 app.adjType = "force-fg";
   14195                 app.adjSource = app.forcingToForeground;
   14196                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14197             }
   14198         }
   14199 
   14200         if (app.foregroundServices) {
   14201             interesting = true;
   14202         }
   14203 
   14204         if (app == mHeavyWeightProcess) {
   14205             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14206                 // We don't want to kill the current heavy-weight process.
   14207                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   14208                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14209                 app.cached = false;
   14210                 app.adjType = "heavy";
   14211             }
   14212             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   14213                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   14214             }
   14215         }
   14216 
   14217         if (app == mHomeProcess) {
   14218             if (adj > ProcessList.HOME_APP_ADJ) {
   14219                 // This process is hosting what we currently consider to be the
   14220                 // home app, so we don't want to let it go into the background.
   14221                 adj = ProcessList.HOME_APP_ADJ;
   14222                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14223                 app.cached = false;
   14224                 app.adjType = "home";
   14225             }
   14226             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   14227                 procState = ActivityManager.PROCESS_STATE_HOME;
   14228             }
   14229         }
   14230 
   14231         if (app == mPreviousProcess && app.activities.size() > 0) {
   14232             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   14233                 // This was the previous process that showed UI to the user.
   14234                 // We want to try to keep it around more aggressively, to give
   14235                 // a good experience around switching between two apps.
   14236                 adj = ProcessList.PREVIOUS_APP_ADJ;
   14237                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14238                 app.cached = false;
   14239                 app.adjType = "previous";
   14240             }
   14241             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   14242                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   14243             }
   14244         }
   14245 
   14246         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   14247                 + " reason=" + app.adjType);
   14248 
   14249         // By default, we use the computed adjustment.  It may be changed if
   14250         // there are applications dependent on our services or providers, but
   14251         // this gives us a baseline and makes sure we don't get into an
   14252         // infinite recursion.
   14253         app.adjSeq = mAdjSeq;
   14254         app.curRawAdj = adj;
   14255         app.hasStartedServices = false;
   14256 
   14257         if (mBackupTarget != null && app == mBackupTarget.app) {
   14258             // If possible we want to avoid killing apps while they're being backed up
   14259             if (adj > ProcessList.BACKUP_APP_ADJ) {
   14260                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   14261                 adj = ProcessList.BACKUP_APP_ADJ;
   14262                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14263                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14264                 }
   14265                 app.adjType = "backup";
   14266                 app.cached = false;
   14267             }
   14268             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   14269                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   14270             }
   14271         }
   14272 
   14273         boolean mayBeTop = false;
   14274 
   14275         for (int is = app.services.size()-1;
   14276                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14277                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14278                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14279                 is--) {
   14280             ServiceRecord s = app.services.valueAt(is);
   14281             if (s.startRequested) {
   14282                 app.hasStartedServices = true;
   14283                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   14284                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   14285                 }
   14286                 if (app.hasShownUi && app != mHomeProcess) {
   14287                     // If this process has shown some UI, let it immediately
   14288                     // go to the LRU list because it may be pretty heavy with
   14289                     // UI stuff.  We'll tag it with a label just to help
   14290                     // debug and understand what is going on.
   14291                     if (adj > ProcessList.SERVICE_ADJ) {
   14292                         app.adjType = "cch-started-ui-services";
   14293                     }
   14294                 } else {
   14295                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14296                         // This service has seen some activity within
   14297                         // recent memory, so we will keep its process ahead
   14298                         // of the background processes.
   14299                         if (adj > ProcessList.SERVICE_ADJ) {
   14300                             adj = ProcessList.SERVICE_ADJ;
   14301                             app.adjType = "started-services";
   14302                             app.cached = false;
   14303                         }
   14304                     }
   14305                     // If we have let the service slide into the background
   14306                     // state, still have some text describing what it is doing
   14307                     // even though the service no longer has an impact.
   14308                     if (adj > ProcessList.SERVICE_ADJ) {
   14309                         app.adjType = "cch-started-services";
   14310                     }
   14311                 }
   14312                 // Don't kill this process because it is doing work; it
   14313                 // has said it is doing work.
   14314                 app.keeping = true;
   14315             }
   14316             for (int conni = s.connections.size()-1;
   14317                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14318                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14319                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14320                     conni--) {
   14321                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   14322                 for (int i = 0;
   14323                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   14324                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14325                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   14326                         i++) {
   14327                     // XXX should compute this based on the max of
   14328                     // all connected clients.
   14329                     ConnectionRecord cr = clist.get(i);
   14330                     if (cr.binding.client == app) {
   14331                         // Binding to ourself is not interesting.
   14332                         continue;
   14333                     }
   14334                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   14335                         ProcessRecord client = cr.binding.client;
   14336                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   14337                                 TOP_APP, doingAll, now);
   14338                         int clientProcState = client.curProcState;
   14339                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14340                             // If the other app is cached for any reason, for purposes here
   14341                             // we are going to consider it empty.  The specific cached state
   14342                             // doesn't propagate except under certain conditions.
   14343                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14344                         }
   14345                         String adjType = null;
   14346                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   14347                             // Not doing bind OOM management, so treat
   14348                             // this guy more like a started service.
   14349                             if (app.hasShownUi && app != mHomeProcess) {
   14350                                 // If this process has shown some UI, let it immediately
   14351                                 // go to the LRU list because it may be pretty heavy with
   14352                                 // UI stuff.  We'll tag it with a label just to help
   14353                                 // debug and understand what is going on.
   14354                                 if (adj > clientAdj) {
   14355                                     adjType = "cch-bound-ui-services";
   14356                                 }
   14357                                 app.cached = false;
   14358                                 clientAdj = adj;
   14359                                 clientProcState = procState;
   14360                             } else {
   14361                                 if (now >= (s.lastActivity
   14362                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14363                                     // This service has not seen activity within
   14364                                     // recent memory, so allow it to drop to the
   14365                                     // LRU list if there is no other reason to keep
   14366                                     // it around.  We'll also tag it with a label just
   14367                                     // to help debug and undertand what is going on.
   14368                                     if (adj > clientAdj) {
   14369                                         adjType = "cch-bound-services";
   14370                                     }
   14371                                     clientAdj = adj;
   14372                                 }
   14373                             }
   14374                         } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
   14375                             if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
   14376                                 // If this connection is keeping the service
   14377                                 // created, then we want to try to better follow
   14378                                 // its memory management semantics for activities.
   14379                                 // That is, if it is sitting in the background
   14380                                 // LRU list as a cached process (with activities),
   14381                                 // we don't want the service it is connected to
   14382                                 // to go into the empty LRU and quickly get killed,
   14383                                 // because all we'll do is just end up restarting
   14384                                 // the service.
   14385                                 if (client.hasActivities) {
   14386                                     if (procState >
   14387                                             ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) {
   14388                                         procState =
   14389                                                 ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   14390                                         app.adjType = "cch-client-act";
   14391                                     }
   14392                                     app.hasClientActivities = true;
   14393                                 }
   14394                             }
   14395                         }
   14396                         if (adj > clientAdj) {
   14397                             // If this process has recently shown UI, and
   14398                             // the process that is binding to it is less
   14399                             // important than being visible, then we don't
   14400                             // care about the binding as much as we care
   14401                             // about letting this process get into the LRU
   14402                             // list to be killed and restarted if needed for
   14403                             // memory.
   14404                             if (app.hasShownUi && app != mHomeProcess
   14405                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14406                                 adjType = "cch-bound-ui-services";
   14407                             } else {
   14408                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   14409                                         |Context.BIND_IMPORTANT)) != 0) {
   14410                                     adj = clientAdj;
   14411                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   14412                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   14413                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14414                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14415                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   14416                                     adj = clientAdj;
   14417                                 } else {
   14418                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14419                                         adj = ProcessList.VISIBLE_APP_ADJ;
   14420                                     }
   14421                                 }
   14422                                 if (!client.cached) {
   14423                                     app.cached = false;
   14424                                 }
   14425                                 if (client.keeping) {
   14426                                     app.keeping = true;
   14427                                 }
   14428                                 adjType = "service";
   14429                             }
   14430                         }
   14431                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14432                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14433                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14434                             }
   14435                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14436                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14437                                     // Special handling of clients who are in the top state.
   14438                                     // We *may* want to consider this process to be in the
   14439                                     // top state as well, but only if there is not another
   14440                                     // reason for it to be running.  Being on the top is a
   14441                                     // special state, meaning you are specifically running
   14442                                     // for the current top app.  If the process is already
   14443                                     // running in the background for some other reason, it
   14444                                     // is more important to continue considering it to be
   14445                                     // in the background state.
   14446                                     mayBeTop = true;
   14447                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14448                                 } else {
   14449                                     // Special handling for above-top states (persistent
   14450                                     // processes).  These should not bring the current process
   14451                                     // into the top state, since they are not on top.  Instead
   14452                                     // give them the best state after that.
   14453                                     clientProcState =
   14454                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14455                                 }
   14456                             }
   14457                         } else {
   14458                             if (clientProcState <
   14459                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14460                                 clientProcState =
   14461                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14462                             }
   14463                         }
   14464                         if (procState > clientProcState) {
   14465                             procState = clientProcState;
   14466                         }
   14467                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   14468                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   14469                             app.pendingUiClean = true;
   14470                         }
   14471                         if (adjType != null) {
   14472                             app.adjType = adjType;
   14473                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14474                                     .REASON_SERVICE_IN_USE;
   14475                             app.adjSource = cr.binding.client;
   14476                             app.adjSourceOom = clientAdj;
   14477                             app.adjTarget = s.name;
   14478                         }
   14479                     }
   14480                     final ActivityRecord a = cr.activity;
   14481                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   14482                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   14483                                 (a.visible || a.state == ActivityState.RESUMED
   14484                                  || a.state == ActivityState.PAUSING)) {
   14485                             adj = ProcessList.FOREGROUND_APP_ADJ;
   14486                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14487                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14488                             }
   14489                             app.cached = false;
   14490                             app.adjType = "service";
   14491                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14492                                     .REASON_SERVICE_IN_USE;
   14493                             app.adjSource = a;
   14494                             app.adjSourceOom = adj;
   14495                             app.adjTarget = s.name;
   14496                         }
   14497                     }
   14498                 }
   14499             }
   14500         }
   14501 
   14502         for (int provi = app.pubProviders.size()-1;
   14503                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14504                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14505                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14506                 provi--) {
   14507             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   14508             for (int i = cpr.connections.size()-1;
   14509                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14510                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14511                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14512                     i--) {
   14513                 ContentProviderConnection conn = cpr.connections.get(i);
   14514                 ProcessRecord client = conn.client;
   14515                 if (client == app) {
   14516                     // Being our own client is not interesting.
   14517                     continue;
   14518                 }
   14519                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   14520                 int clientProcState = client.curProcState;
   14521                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14522                     // If the other app is cached for any reason, for purposes here
   14523                     // we are going to consider it empty.
   14524                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14525                 }
   14526                 if (adj > clientAdj) {
   14527                     if (app.hasShownUi && app != mHomeProcess
   14528                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14529                         app.adjType = "cch-ui-provider";
   14530                     } else {
   14531                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   14532                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   14533                         app.adjType = "provider";
   14534                     }
   14535                     app.cached &= client.cached;
   14536                     app.keeping |= client.keeping;
   14537                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14538                             .REASON_PROVIDER_IN_USE;
   14539                     app.adjSource = client;
   14540                     app.adjSourceOom = clientAdj;
   14541                     app.adjTarget = cpr.name;
   14542                 }
   14543                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14544                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14545                         // Special handling of clients who are in the top state.
   14546                         // We *may* want to consider this process to be in the
   14547                         // top state as well, but only if there is not another
   14548                         // reason for it to be running.  Being on the top is a
   14549                         // special state, meaning you are specifically running
   14550                         // for the current top app.  If the process is already
   14551                         // running in the background for some other reason, it
   14552                         // is more important to continue considering it to be
   14553                         // in the background state.
   14554                         mayBeTop = true;
   14555                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14556                     } else {
   14557                         // Special handling for above-top states (persistent
   14558                         // processes).  These should not bring the current process
   14559                         // into the top state, since they are not on top.  Instead
   14560                         // give them the best state after that.
   14561                         clientProcState =
   14562                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14563                     }
   14564                 }
   14565                 if (procState > clientProcState) {
   14566                     procState = clientProcState;
   14567                 }
   14568                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14569                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14570                 }
   14571             }
   14572             // If the provider has external (non-framework) process
   14573             // dependencies, ensure that its adjustment is at least
   14574             // FOREGROUND_APP_ADJ.
   14575             if (cpr.hasExternalProcessHandles()) {
   14576                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   14577                     adj = ProcessList.FOREGROUND_APP_ADJ;
   14578                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14579                     app.cached = false;
   14580                     app.keeping = true;
   14581                     app.adjType = "provider";
   14582                     app.adjTarget = cpr.name;
   14583                 }
   14584                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   14585                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14586                 }
   14587             }
   14588         }
   14589 
   14590         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   14591             // A client of one of our services or providers is in the top state.  We
   14592             // *may* want to be in the top state, but not if we are already running in
   14593             // the background for some other reason.  For the decision here, we are going
   14594             // to pick out a few specific states that we want to remain in when a client
   14595             // is top (states that tend to be longer-term) and otherwise allow it to go
   14596             // to the top state.
   14597             switch (procState) {
   14598                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   14599                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   14600                 case ActivityManager.PROCESS_STATE_SERVICE:
   14601                     // These all are longer-term states, so pull them up to the top
   14602                     // of the background states, but not all the way to the top state.
   14603                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14604                     break;
   14605                 default:
   14606                     // Otherwise, top is a better choice, so take it.
   14607                     procState = ActivityManager.PROCESS_STATE_TOP;
   14608                     break;
   14609             }
   14610         }
   14611 
   14612         if (adj == ProcessList.SERVICE_ADJ) {
   14613             if (doingAll) {
   14614                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   14615                 mNewNumServiceProcs++;
   14616                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   14617                 if (!app.serviceb) {
   14618                     // This service isn't far enough down on the LRU list to
   14619                     // normally be a B service, but if we are low on RAM and it
   14620                     // is large we want to force it down since we would prefer to
   14621                     // keep launcher over it.
   14622                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   14623                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   14624                         app.serviceHighRam = true;
   14625                         app.serviceb = true;
   14626                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   14627                     } else {
   14628                         mNewNumAServiceProcs++;
   14629                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   14630                     }
   14631                 } else {
   14632                     app.serviceHighRam = false;
   14633                 }
   14634             }
   14635             if (app.serviceb) {
   14636                 adj = ProcessList.SERVICE_B_ADJ;
   14637             }
   14638         }
   14639 
   14640         app.curRawAdj = adj;
   14641 
   14642         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14643         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14644         if (adj > app.maxAdj) {
   14645             adj = app.maxAdj;
   14646             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14647                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14648             }
   14649         }
   14650         if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
   14651             app.keeping = true;
   14652         }
   14653 
   14654         // Do final modification to adj.  Everything we do between here and applying
   14655         // the final setAdj must be done in this function, because we will also use
   14656         // it when computing the final cached adj later.  Note that we don't need to
   14657         // worry about this for max adj above, since max adj will always be used to
   14658         // keep it out of the cached vaues.
   14659         adj = app.modifyRawOomAdj(adj);
   14660 
   14661         app.curProcState = procState;
   14662 
   14663         int importance = app.memImportance;
   14664         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   14665             app.curAdj = adj;
   14666             app.curSchedGroup = schedGroup;
   14667             if (!interesting) {
   14668                 // For this reporting, if there is not something explicitly
   14669                 // interesting in this process then we will push it to the
   14670                 // background importance.
   14671                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14672             } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14673                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14674             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   14675                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14676             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   14677                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14678             } else if (adj >= ProcessList.SERVICE_ADJ) {
   14679                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14680             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14681                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   14682             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14683                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   14684             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   14685                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   14686             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   14687                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   14688             } else {
   14689                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   14690             }
   14691         }
   14692 
   14693         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   14694         if (foregroundActivities != app.foregroundActivities) {
   14695             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   14696         }
   14697         if (changes != 0) {
   14698             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   14699             app.memImportance = importance;
   14700             app.foregroundActivities = foregroundActivities;
   14701             int i = mPendingProcessChanges.size()-1;
   14702             ProcessChangeItem item = null;
   14703             while (i >= 0) {
   14704                 item = mPendingProcessChanges.get(i);
   14705                 if (item.pid == app.pid) {
   14706                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   14707                     break;
   14708                 }
   14709                 i--;
   14710             }
   14711             if (i < 0) {
   14712                 // No existing item in pending changes; need a new one.
   14713                 final int NA = mAvailProcessChanges.size();
   14714                 if (NA > 0) {
   14715                     item = mAvailProcessChanges.remove(NA-1);
   14716                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   14717                 } else {
   14718                     item = new ProcessChangeItem();
   14719                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   14720                 }
   14721                 item.changes = 0;
   14722                 item.pid = app.pid;
   14723                 item.uid = app.info.uid;
   14724                 if (mPendingProcessChanges.size() == 0) {
   14725                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   14726                             "*** Enqueueing dispatch processes changed!");
   14727                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   14728                 }
   14729                 mPendingProcessChanges.add(item);
   14730             }
   14731             item.changes |= changes;
   14732             item.importance = importance;
   14733             item.foregroundActivities = foregroundActivities;
   14734             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   14735                     + Integer.toHexString(System.identityHashCode(item))
   14736                     + " " + app.toShortString() + ": changes=" + item.changes
   14737                     + " importance=" + item.importance
   14738                     + " foreground=" + item.foregroundActivities
   14739                     + " type=" + app.adjType + " source=" + app.adjSource
   14740                     + " target=" + app.adjTarget);
   14741         }
   14742 
   14743         return app.curRawAdj;
   14744     }
   14745 
   14746     /**
   14747      * Schedule PSS collection of a process.
   14748      */
   14749     void requestPssLocked(ProcessRecord proc, int procState) {
   14750         if (mPendingPssProcesses.contains(proc)) {
   14751             return;
   14752         }
   14753         if (mPendingPssProcesses.size() == 0) {
   14754             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   14755         }
   14756         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   14757         proc.pssProcState = procState;
   14758         mPendingPssProcesses.add(proc);
   14759     }
   14760 
   14761     /**
   14762      * Schedule PSS collection of all processes.
   14763      */
   14764     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   14765         if (!always) {
   14766             if (now < (mLastFullPssTime +
   14767                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   14768                 return;
   14769             }
   14770         }
   14771         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   14772         mLastFullPssTime = now;
   14773         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   14774         mPendingPssProcesses.clear();
   14775         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   14776             ProcessRecord app = mLruProcesses.get(i);
   14777             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   14778                 app.pssProcState = app.setProcState;
   14779                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   14780                         mSleeping, now);
   14781                 mPendingPssProcesses.add(app);
   14782             }
   14783         }
   14784         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   14785     }
   14786 
   14787     /**
   14788      * Ask a given process to GC right now.
   14789      */
   14790     final void performAppGcLocked(ProcessRecord app) {
   14791         try {
   14792             app.lastRequestedGc = SystemClock.uptimeMillis();
   14793             if (app.thread != null) {
   14794                 if (app.reportLowMemory) {
   14795                     app.reportLowMemory = false;
   14796                     app.thread.scheduleLowMemory();
   14797                 } else {
   14798                     app.thread.processInBackground();
   14799                 }
   14800             }
   14801         } catch (Exception e) {
   14802             // whatever.
   14803         }
   14804     }
   14805 
   14806     /**
   14807      * Returns true if things are idle enough to perform GCs.
   14808      */
   14809     private final boolean canGcNowLocked() {
   14810         boolean processingBroadcasts = false;
   14811         for (BroadcastQueue q : mBroadcastQueues) {
   14812             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   14813                 processingBroadcasts = true;
   14814             }
   14815         }
   14816         return !processingBroadcasts
   14817                 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
   14818     }
   14819 
   14820     /**
   14821      * Perform GCs on all processes that are waiting for it, but only
   14822      * if things are idle.
   14823      */
   14824     final void performAppGcsLocked() {
   14825         final int N = mProcessesToGc.size();
   14826         if (N <= 0) {
   14827             return;
   14828         }
   14829         if (canGcNowLocked()) {
   14830             while (mProcessesToGc.size() > 0) {
   14831                 ProcessRecord proc = mProcessesToGc.remove(0);
   14832                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   14833                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   14834                             <= SystemClock.uptimeMillis()) {
   14835                         // To avoid spamming the system, we will GC processes one
   14836                         // at a time, waiting a few seconds between each.
   14837                         performAppGcLocked(proc);
   14838                         scheduleAppGcsLocked();
   14839                         return;
   14840                     } else {
   14841                         // It hasn't been long enough since we last GCed this
   14842                         // process...  put it in the list to wait for its time.
   14843                         addProcessToGcListLocked(proc);
   14844                         break;
   14845                     }
   14846                 }
   14847             }
   14848 
   14849             scheduleAppGcsLocked();
   14850         }
   14851     }
   14852 
   14853     /**
   14854      * If all looks good, perform GCs on all processes waiting for them.
   14855      */
   14856     final void performAppGcsIfAppropriateLocked() {
   14857         if (canGcNowLocked()) {
   14858             performAppGcsLocked();
   14859             return;
   14860         }
   14861         // Still not idle, wait some more.
   14862         scheduleAppGcsLocked();
   14863     }
   14864 
   14865     /**
   14866      * Schedule the execution of all pending app GCs.
   14867      */
   14868     final void scheduleAppGcsLocked() {
   14869         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   14870 
   14871         if (mProcessesToGc.size() > 0) {
   14872             // Schedule a GC for the time to the next process.
   14873             ProcessRecord proc = mProcessesToGc.get(0);
   14874             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   14875 
   14876             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   14877             long now = SystemClock.uptimeMillis();
   14878             if (when < (now+GC_TIMEOUT)) {
   14879                 when = now + GC_TIMEOUT;
   14880             }
   14881             mHandler.sendMessageAtTime(msg, when);
   14882         }
   14883     }
   14884 
   14885     /**
   14886      * Add a process to the array of processes waiting to be GCed.  Keeps the
   14887      * list in sorted order by the last GC time.  The process can't already be
   14888      * on the list.
   14889      */
   14890     final void addProcessToGcListLocked(ProcessRecord proc) {
   14891         boolean added = false;
   14892         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   14893             if (mProcessesToGc.get(i).lastRequestedGc <
   14894                     proc.lastRequestedGc) {
   14895                 added = true;
   14896                 mProcessesToGc.add(i+1, proc);
   14897                 break;
   14898             }
   14899         }
   14900         if (!added) {
   14901             mProcessesToGc.add(0, proc);
   14902         }
   14903     }
   14904 
   14905     /**
   14906      * Set up to ask a process to GC itself.  This will either do it
   14907      * immediately, or put it on the list of processes to gc the next
   14908      * time things are idle.
   14909      */
   14910     final void scheduleAppGcLocked(ProcessRecord app) {
   14911         long now = SystemClock.uptimeMillis();
   14912         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   14913             return;
   14914         }
   14915         if (!mProcessesToGc.contains(app)) {
   14916             addProcessToGcListLocked(app);
   14917             scheduleAppGcsLocked();
   14918         }
   14919     }
   14920 
   14921     final void checkExcessivePowerUsageLocked(boolean doKills) {
   14922         updateCpuStatsNow();
   14923 
   14924         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   14925         boolean doWakeKills = doKills;
   14926         boolean doCpuKills = doKills;
   14927         if (mLastPowerCheckRealtime == 0) {
   14928             doWakeKills = false;
   14929         }
   14930         if (mLastPowerCheckUptime == 0) {
   14931             doCpuKills = false;
   14932         }
   14933         if (stats.isScreenOn()) {
   14934             doWakeKills = false;
   14935         }
   14936         final long curRealtime = SystemClock.elapsedRealtime();
   14937         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   14938         final long curUptime = SystemClock.uptimeMillis();
   14939         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   14940         mLastPowerCheckRealtime = curRealtime;
   14941         mLastPowerCheckUptime = curUptime;
   14942         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   14943             doWakeKills = false;
   14944         }
   14945         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   14946             doCpuKills = false;
   14947         }
   14948         int i = mLruProcesses.size();
   14949         while (i > 0) {
   14950             i--;
   14951             ProcessRecord app = mLruProcesses.get(i);
   14952             if (!app.keeping) {
   14953                 long wtime;
   14954                 synchronized (stats) {
   14955                     wtime = stats.getProcessWakeTime(app.info.uid,
   14956                             app.pid, curRealtime);
   14957                 }
   14958                 long wtimeUsed = wtime - app.lastWakeTime;
   14959                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   14960                 if (DEBUG_POWER) {
   14961                     StringBuilder sb = new StringBuilder(128);
   14962                     sb.append("Wake for ");
   14963                     app.toShortString(sb);
   14964                     sb.append(": over ");
   14965                     TimeUtils.formatDuration(realtimeSince, sb);
   14966                     sb.append(" used ");
   14967                     TimeUtils.formatDuration(wtimeUsed, sb);
   14968                     sb.append(" (");
   14969                     sb.append((wtimeUsed*100)/realtimeSince);
   14970                     sb.append("%)");
   14971                     Slog.i(TAG, sb.toString());
   14972                     sb.setLength(0);
   14973                     sb.append("CPU for ");
   14974                     app.toShortString(sb);
   14975                     sb.append(": over ");
   14976                     TimeUtils.formatDuration(uptimeSince, sb);
   14977                     sb.append(" used ");
   14978                     TimeUtils.formatDuration(cputimeUsed, sb);
   14979                     sb.append(" (");
   14980                     sb.append((cputimeUsed*100)/uptimeSince);
   14981                     sb.append("%)");
   14982                     Slog.i(TAG, sb.toString());
   14983                 }
   14984                 // If a process has held a wake lock for more
   14985                 // than 50% of the time during this period,
   14986                 // that sounds bad.  Kill!
   14987                 if (doWakeKills && realtimeSince > 0
   14988                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   14989                     synchronized (stats) {
   14990                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   14991                                 realtimeSince, wtimeUsed);
   14992                     }
   14993                     killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
   14994                             + " during " + realtimeSince);
   14995                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   14996                 } else if (doCpuKills && uptimeSince > 0
   14997                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   14998                     synchronized (stats) {
   14999                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   15000                                 uptimeSince, cputimeUsed);
   15001                     }
   15002                     killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
   15003                             + " during " + uptimeSince);
   15004                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   15005                 } else {
   15006                     app.lastWakeTime = wtime;
   15007                     app.lastCpuTime = app.curCpuTime;
   15008                 }
   15009             }
   15010         }
   15011     }
   15012 
   15013     private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
   15014             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15015         boolean success = true;
   15016 
   15017         if (app.curRawAdj != app.setRawAdj) {
   15018             if (wasKeeping && !app.keeping) {
   15019                 // This app is no longer something we want to keep.  Note
   15020                 // its current wake lock time to later know to kill it if
   15021                 // it is not behaving well.
   15022                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15023                 synchronized (stats) {
   15024                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   15025                             app.pid, SystemClock.elapsedRealtime());
   15026                 }
   15027                 app.lastCpuTime = app.curCpuTime;
   15028             }
   15029 
   15030             app.setRawAdj = app.curRawAdj;
   15031         }
   15032 
   15033         if (app.curAdj != app.setAdj) {
   15034             if (Process.setOomAdj(app.pid, app.curAdj)) {
   15035                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   15036                     TAG, "Set " + app.pid + " " + app.processName +
   15037                     " adj " + app.curAdj + ": " + app.adjType);
   15038                 app.setAdj = app.curAdj;
   15039             } else {
   15040                 success = false;
   15041                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   15042             }
   15043         }
   15044         if (app.setSchedGroup != app.curSchedGroup) {
   15045             app.setSchedGroup = app.curSchedGroup;
   15046             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15047                     "Setting process group of " + app.processName
   15048                     + " to " + app.curSchedGroup);
   15049             if (app.waitingToKill != null &&
   15050                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   15051                 killUnneededProcessLocked(app, app.waitingToKill);
   15052                 success = false;
   15053             } else {
   15054                 if (true) {
   15055                     long oldId = Binder.clearCallingIdentity();
   15056                     try {
   15057                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   15058                     } catch (Exception e) {
   15059                         Slog.w(TAG, "Failed setting process group of " + app.pid
   15060                                 + " to " + app.curSchedGroup);
   15061                         e.printStackTrace();
   15062                     } finally {
   15063                         Binder.restoreCallingIdentity(oldId);
   15064                     }
   15065                 } else {
   15066                     if (app.thread != null) {
   15067                         try {
   15068                             app.thread.setSchedulingGroup(app.curSchedGroup);
   15069                         } catch (RemoteException e) {
   15070                         }
   15071                     }
   15072                 }
   15073                 Process.setSwappiness(app.pid,
   15074                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   15075             }
   15076         }
   15077         if (app.repProcState != app.curProcState) {
   15078             app.repProcState = app.curProcState;
   15079             if (!reportingProcessState && app.thread != null) {
   15080                 try {
   15081                     if (false) {
   15082                         //RuntimeException h = new RuntimeException("here");
   15083                         Slog.i(TAG, "Sending new process state " + app.repProcState
   15084                                 + " to " + app /*, h*/);
   15085                     }
   15086                     app.thread.setProcessState(app.repProcState);
   15087                 } catch (RemoteException e) {
   15088                 }
   15089             }
   15090         }
   15091         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   15092                 app.setProcState)) {
   15093             app.lastStateTime = now;
   15094             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   15095                     mSleeping, now);
   15096             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   15097                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   15098                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   15099                     + (app.nextPssTime-now) + ": " + app);
   15100         } else {
   15101             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   15102                     && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
   15103                 requestPssLocked(app, app.setProcState);
   15104                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   15105                         mSleeping, now);
   15106             } else if (false && DEBUG_PSS) {
   15107                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   15108             }
   15109         }
   15110         if (app.setProcState != app.curProcState) {
   15111             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15112                     "Proc state change of " + app.processName
   15113                     + " to " + app.curProcState);
   15114             app.setProcState = app.curProcState;
   15115             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   15116                 app.notCachedSinceIdle = false;
   15117             }
   15118             if (!doingAll) {
   15119                 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
   15120             } else {
   15121                 app.procStateChanged = true;
   15122             }
   15123         }
   15124         return success;
   15125     }
   15126 
   15127     private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
   15128         if (proc.thread != null && proc.baseProcessTracker != null) {
   15129             proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   15130         }
   15131     }
   15132 
   15133     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   15134             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15135         if (app.thread == null) {
   15136             return false;
   15137         }
   15138 
   15139         final boolean wasKeeping = app.keeping;
   15140 
   15141         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   15142 
   15143         return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
   15144                 reportingProcessState, now);
   15145     }
   15146 
   15147     private final ActivityRecord resumedAppLocked() {
   15148         return mStackSupervisor.resumedAppLocked();
   15149     }
   15150 
   15151     final boolean updateOomAdjLocked(ProcessRecord app) {
   15152         return updateOomAdjLocked(app, false);
   15153     }
   15154 
   15155     final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
   15156         final ActivityRecord TOP_ACT = resumedAppLocked();
   15157         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15158         final boolean wasCached = app.cached;
   15159 
   15160         mAdjSeq++;
   15161 
   15162         // This is the desired cached adjusment we want to tell it to use.
   15163         // If our app is currently cached, we know it, and that is it.  Otherwise,
   15164         // we don't know it yet, and it needs to now be cached we will then
   15165         // need to do a complete oom adj.
   15166         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   15167                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   15168         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
   15169                 SystemClock.uptimeMillis());
   15170         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   15171             // Changed to/from cached state, so apps after it in the LRU
   15172             // list may also be changed.
   15173             updateOomAdjLocked();
   15174         }
   15175         return success;
   15176     }
   15177 
   15178     final void updateOomAdjLocked() {
   15179         final ActivityRecord TOP_ACT = resumedAppLocked();
   15180         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15181         final long now = SystemClock.uptimeMillis();
   15182         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   15183         final int N = mLruProcesses.size();
   15184 
   15185         if (false) {
   15186             RuntimeException e = new RuntimeException();
   15187             e.fillInStackTrace();
   15188             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   15189         }
   15190 
   15191         mAdjSeq++;
   15192         mNewNumServiceProcs = 0;
   15193         mNewNumAServiceProcs = 0;
   15194 
   15195         final int emptyProcessLimit;
   15196         final int cachedProcessLimit;
   15197         if (mProcessLimit <= 0) {
   15198             emptyProcessLimit = cachedProcessLimit = 0;
   15199         } else if (mProcessLimit == 1) {
   15200             emptyProcessLimit = 1;
   15201             cachedProcessLimit = 0;
   15202         } else {
   15203             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   15204             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   15205         }
   15206 
   15207         // Let's determine how many processes we have running vs.
   15208         // how many slots we have for background processes; we may want
   15209         // to put multiple processes in a slot of there are enough of
   15210         // them.
   15211         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   15212                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   15213         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   15214         if (numEmptyProcs > cachedProcessLimit) {
   15215             // If there are more empty processes than our limit on cached
   15216             // processes, then use the cached process limit for the factor.
   15217             // This ensures that the really old empty processes get pushed
   15218             // down to the bottom, so if we are running low on memory we will
   15219             // have a better chance at keeping around more cached processes
   15220             // instead of a gazillion empty processes.
   15221             numEmptyProcs = cachedProcessLimit;
   15222         }
   15223         int emptyFactor = numEmptyProcs/numSlots;
   15224         if (emptyFactor < 1) emptyFactor = 1;
   15225         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   15226         if (cachedFactor < 1) cachedFactor = 1;
   15227         int stepCached = 0;
   15228         int stepEmpty = 0;
   15229         int numCached = 0;
   15230         int numEmpty = 0;
   15231         int numTrimming = 0;
   15232 
   15233         mNumNonCachedProcs = 0;
   15234         mNumCachedHiddenProcs = 0;
   15235 
   15236         // First update the OOM adjustment for each of the
   15237         // application processes based on their current state.
   15238         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15239         int nextCachedAdj = curCachedAdj+1;
   15240         int curClientCachedAdj = curCachedAdj+1;
   15241         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15242         int nextEmptyAdj = curEmptyAdj+2;
   15243         for (int i=N-1; i>=0; i--) {
   15244             ProcessRecord app = mLruProcesses.get(i);
   15245             if (!app.killedByAm && app.thread != null) {
   15246                 app.procStateChanged = false;
   15247                 final boolean wasKeeping = app.keeping;
   15248                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   15249 
   15250                 // If we haven't yet assigned the final cached adj
   15251                 // to the process, do that now.
   15252                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   15253                     switch (app.curProcState) {
   15254                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15255                             // This process is a cached process holding activities...
   15256                             // assign it the next cached value for that type, and then
   15257                             // step that cached level.
   15258                             app.curRawAdj = curCachedAdj;
   15259                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   15260                             if (curCachedAdj != nextCachedAdj) {
   15261                                 stepCached++;
   15262                                 if (stepCached >= cachedFactor) {
   15263                                     stepCached = 0;
   15264                                     curCachedAdj = nextCachedAdj;
   15265                                     nextCachedAdj += 2;
   15266                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15267                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15268                                     }
   15269                                     if (curClientCachedAdj <= curCachedAdj) {
   15270                                         curClientCachedAdj = curCachedAdj + 1;
   15271                                         if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15272                                             curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15273                                         }
   15274                                     }
   15275                                 }
   15276                             }
   15277                             break;
   15278                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15279                             // Special case for cached client processes...  just step
   15280                             // down from after regular cached processes.
   15281                             app.curRawAdj = curClientCachedAdj;
   15282                             app.curAdj = app.modifyRawOomAdj(curClientCachedAdj);
   15283                             curClientCachedAdj++;
   15284                             if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15285                                 curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15286                             }
   15287                             break;
   15288                         default:
   15289                             // For everything else, assign next empty cached process
   15290                             // level and bump that up.  Note that this means that
   15291                             // long-running services that have dropped down to the
   15292                             // cached level will be treated as empty (since their process
   15293                             // state is still as a service), which is what we want.
   15294                             app.curRawAdj = curEmptyAdj;
   15295                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   15296                             if (curEmptyAdj != nextEmptyAdj) {
   15297                                 stepEmpty++;
   15298                                 if (stepEmpty >= emptyFactor) {
   15299                                     stepEmpty = 0;
   15300                                     curEmptyAdj = nextEmptyAdj;
   15301                                     nextEmptyAdj += 2;
   15302                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15303                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15304                                     }
   15305                                 }
   15306                             }
   15307                             break;
   15308                     }
   15309                 }
   15310 
   15311                 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
   15312 
   15313                 // Count the number of process types.
   15314                 switch (app.curProcState) {
   15315                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15316                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15317                         mNumCachedHiddenProcs++;
   15318                         numCached++;
   15319                         if (numCached > cachedProcessLimit) {
   15320                             killUnneededProcessLocked(app, "cached #" + numCached);
   15321                         }
   15322                         break;
   15323                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   15324                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   15325                                 && app.lastActivityTime < oldTime) {
   15326                             killUnneededProcessLocked(app, "empty for "
   15327                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   15328                                     / 1000) + "s");
   15329                         } else {
   15330                             numEmpty++;
   15331                             if (numEmpty > emptyProcessLimit) {
   15332                                 killUnneededProcessLocked(app, "empty #" + numEmpty);
   15333                             }
   15334                         }
   15335                         break;
   15336                     default:
   15337                         mNumNonCachedProcs++;
   15338                         break;
   15339                 }
   15340 
   15341                 if (app.isolated && app.services.size() <= 0) {
   15342                     // If this is an isolated process, and there are no
   15343                     // services running in it, then the process is no longer
   15344                     // needed.  We agressively kill these because we can by
   15345                     // definition not re-use the same process again, and it is
   15346                     // good to avoid having whatever code was running in them
   15347                     // left sitting around after no longer needed.
   15348                     killUnneededProcessLocked(app, "isolated not needed");
   15349                 }
   15350 
   15351                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15352                         && !app.killedByAm) {
   15353                     numTrimming++;
   15354                 }
   15355             }
   15356         }
   15357 
   15358         mNumServiceProcs = mNewNumServiceProcs;
   15359 
   15360         // Now determine the memory trimming level of background processes.
   15361         // Unfortunately we need to start at the back of the list to do this
   15362         // properly.  We only do this if the number of background apps we
   15363         // are managing to keep around is less than half the maximum we desire;
   15364         // if we are keeping a good number around, we'll let them use whatever
   15365         // memory they want.
   15366         final int numCachedAndEmpty = numCached + numEmpty;
   15367         int memFactor;
   15368         if (numCached <= ProcessList.TRIM_CACHED_APPS
   15369                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   15370             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   15371                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   15372             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   15373                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   15374             } else {
   15375                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   15376             }
   15377         } else {
   15378             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   15379         }
   15380         // We always allow the memory level to go up (better).  We only allow it to go
   15381         // down if we are in a state where that is allowed, *and* the total number of processes
   15382         // has gone down since last time.
   15383         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   15384                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   15385                 + " last=" + mLastNumProcesses);
   15386         if (memFactor > mLastMemoryLevel) {
   15387             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   15388                 memFactor = mLastMemoryLevel;
   15389                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   15390             }
   15391         }
   15392         mLastMemoryLevel = memFactor;
   15393         mLastNumProcesses = mLruProcesses.size();
   15394         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
   15395         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   15396         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   15397             if (mLowRamStartTime == 0) {
   15398                 mLowRamStartTime = now;
   15399             }
   15400             int step = 0;
   15401             int fgTrimLevel;
   15402             switch (memFactor) {
   15403                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   15404                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   15405                     break;
   15406                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   15407                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   15408                     break;
   15409                 default:
   15410                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   15411                     break;
   15412             }
   15413             int factor = numTrimming/3;
   15414             int minFactor = 2;
   15415             if (mHomeProcess != null) minFactor++;
   15416             if (mPreviousProcess != null) minFactor++;
   15417             if (factor < minFactor) factor = minFactor;
   15418             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   15419             for (int i=N-1; i>=0; i--) {
   15420                 ProcessRecord app = mLruProcesses.get(i);
   15421                 if (allChanged || app.procStateChanged) {
   15422                     setProcessTrackerState(app, trackerMemFactor, now);
   15423                     app.procStateChanged = false;
   15424                 }
   15425                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15426                         && !app.killedByAm) {
   15427                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   15428                         try {
   15429                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15430                                     "Trimming memory of " + app.processName
   15431                                     + " to " + curLevel);
   15432                             app.thread.scheduleTrimMemory(curLevel);
   15433                         } catch (RemoteException e) {
   15434                         }
   15435                         if (false) {
   15436                             // For now we won't do this; our memory trimming seems
   15437                             // to be good enough at this point that destroying
   15438                             // activities causes more harm than good.
   15439                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   15440                                     && app != mHomeProcess && app != mPreviousProcess) {
   15441                                 // Need to do this on its own message because the stack may not
   15442                                 // be in a consistent state at this point.
   15443                                 // For these apps we will also finish their activities
   15444                                 // to help them free memory.
   15445                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   15446                             }
   15447                         }
   15448                     }
   15449                     app.trimMemoryLevel = curLevel;
   15450                     step++;
   15451                     if (step >= factor) {
   15452                         step = 0;
   15453                         switch (curLevel) {
   15454                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   15455                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   15456                                 break;
   15457                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   15458                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15459                                 break;
   15460                         }
   15461                     }
   15462                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   15463                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   15464                             && app.thread != null) {
   15465                         try {
   15466                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15467                                     "Trimming memory of heavy-weight " + app.processName
   15468                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15469                             app.thread.scheduleTrimMemory(
   15470                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15471                         } catch (RemoteException e) {
   15472                         }
   15473                     }
   15474                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15475                 } else {
   15476                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15477                             || app.systemNoUi) && app.pendingUiClean) {
   15478                         // If this application is now in the background and it
   15479                         // had done UI, then give it the special trim level to
   15480                         // have it free UI resources.
   15481                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   15482                         if (app.trimMemoryLevel < level && app.thread != null) {
   15483                             try {
   15484                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15485                                         "Trimming memory of bg-ui " + app.processName
   15486                                         + " to " + level);
   15487                                 app.thread.scheduleTrimMemory(level);
   15488                             } catch (RemoteException e) {
   15489                             }
   15490                         }
   15491                         app.pendingUiClean = false;
   15492                     }
   15493                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   15494                         try {
   15495                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15496                                     "Trimming memory of fg " + app.processName
   15497                                     + " to " + fgTrimLevel);
   15498                             app.thread.scheduleTrimMemory(fgTrimLevel);
   15499                         } catch (RemoteException e) {
   15500                         }
   15501                     }
   15502                     app.trimMemoryLevel = fgTrimLevel;
   15503                 }
   15504             }
   15505         } else {
   15506             if (mLowRamStartTime != 0) {
   15507                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   15508                 mLowRamStartTime = 0;
   15509             }
   15510             for (int i=N-1; i>=0; i--) {
   15511                 ProcessRecord app = mLruProcesses.get(i);
   15512                 if (allChanged || app.procStateChanged) {
   15513                     setProcessTrackerState(app, trackerMemFactor, now);
   15514                     app.procStateChanged = false;
   15515                 }
   15516                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15517                         || app.systemNoUi) && app.pendingUiClean) {
   15518                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   15519                             && app.thread != null) {
   15520                         try {
   15521                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15522                                     "Trimming memory of ui hidden " + app.processName
   15523                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15524                             app.thread.scheduleTrimMemory(
   15525                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15526                         } catch (RemoteException e) {
   15527                         }
   15528                     }
   15529                     app.pendingUiClean = false;
   15530                 }
   15531                 app.trimMemoryLevel = 0;
   15532             }
   15533         }
   15534 
   15535         if (mAlwaysFinishActivities) {
   15536             // Need to do this on its own message because the stack may not
   15537             // be in a consistent state at this point.
   15538             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   15539         }
   15540 
   15541         if (allChanged) {
   15542             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   15543         }
   15544 
   15545         if (mProcessStats.shouldWriteNowLocked(now)) {
   15546             mHandler.post(new Runnable() {
   15547                 @Override public void run() {
   15548                     synchronized (ActivityManagerService.this) {
   15549                         mProcessStats.writeStateAsyncLocked();
   15550                     }
   15551                 }
   15552             });
   15553         }
   15554 
   15555         if (DEBUG_OOM_ADJ) {
   15556             Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   15557         }
   15558     }
   15559 
   15560     final void trimApplications() {
   15561         synchronized (this) {
   15562             int i;
   15563 
   15564             // First remove any unused application processes whose package
   15565             // has been removed.
   15566             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   15567                 final ProcessRecord app = mRemovedProcesses.get(i);
   15568                 if (app.activities.size() == 0
   15569                         && app.curReceiver == null && app.services.size() == 0) {
   15570                     Slog.i(
   15571                         TAG, "Exiting empty application process "
   15572                         + app.processName + " ("
   15573                         + (app.thread != null ? app.thread.asBinder() : null)
   15574                         + ")\n");
   15575                     if (app.pid > 0 && app.pid != MY_PID) {
   15576                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   15577                                 app.processName, app.setAdj, "empty");
   15578                         app.killedByAm = true;
   15579                         Process.killProcessQuiet(app.pid);
   15580                     } else {
   15581                         try {
   15582                             app.thread.scheduleExit();
   15583                         } catch (Exception e) {
   15584                             // Ignore exceptions.
   15585                         }
   15586                     }
   15587                     cleanUpApplicationRecordLocked(app, false, true, -1);
   15588                     mRemovedProcesses.remove(i);
   15589 
   15590                     if (app.persistent) {
   15591                         if (app.persistent) {
   15592                             addAppLocked(app.info, false);
   15593                         }
   15594                     }
   15595                 }
   15596             }
   15597 
   15598             // Now update the oom adj for all processes.
   15599             updateOomAdjLocked();
   15600         }
   15601     }
   15602 
   15603     /** This method sends the specified signal to each of the persistent apps */
   15604     public void signalPersistentProcesses(int sig) throws RemoteException {
   15605         if (sig != Process.SIGNAL_USR1) {
   15606             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   15607         }
   15608 
   15609         synchronized (this) {
   15610             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   15611                     != PackageManager.PERMISSION_GRANTED) {
   15612                 throw new SecurityException("Requires permission "
   15613                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   15614             }
   15615 
   15616             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15617                 ProcessRecord r = mLruProcesses.get(i);
   15618                 if (r.thread != null && r.persistent) {
   15619                     Process.sendSignal(r.pid, sig);
   15620                 }
   15621             }
   15622         }
   15623     }
   15624 
   15625     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   15626         if (proc == null || proc == mProfileProc) {
   15627             proc = mProfileProc;
   15628             path = mProfileFile;
   15629             profileType = mProfileType;
   15630             clearProfilerLocked();
   15631         }
   15632         if (proc == null) {
   15633             return;
   15634         }
   15635         try {
   15636             proc.thread.profilerControl(false, path, null, profileType);
   15637         } catch (RemoteException e) {
   15638             throw new IllegalStateException("Process disappeared");
   15639         }
   15640     }
   15641 
   15642     private void clearProfilerLocked() {
   15643         if (mProfileFd != null) {
   15644             try {
   15645                 mProfileFd.close();
   15646             } catch (IOException e) {
   15647             }
   15648         }
   15649         mProfileApp = null;
   15650         mProfileProc = null;
   15651         mProfileFile = null;
   15652         mProfileType = 0;
   15653         mAutoStopProfiler = false;
   15654     }
   15655 
   15656     public boolean profileControl(String process, int userId, boolean start,
   15657             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   15658 
   15659         try {
   15660             synchronized (this) {
   15661                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15662                 // its own permission.
   15663                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15664                         != PackageManager.PERMISSION_GRANTED) {
   15665                     throw new SecurityException("Requires permission "
   15666                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15667                 }
   15668 
   15669                 if (start && fd == null) {
   15670                     throw new IllegalArgumentException("null fd");
   15671                 }
   15672 
   15673                 ProcessRecord proc = null;
   15674                 if (process != null) {
   15675                     proc = findProcessLocked(process, userId, "profileControl");
   15676                 }
   15677 
   15678                 if (start && (proc == null || proc.thread == null)) {
   15679                     throw new IllegalArgumentException("Unknown process: " + process);
   15680                 }
   15681 
   15682                 if (start) {
   15683                     stopProfilerLocked(null, null, 0);
   15684                     setProfileApp(proc.info, proc.processName, path, fd, false);
   15685                     mProfileProc = proc;
   15686                     mProfileType = profileType;
   15687                     try {
   15688                         fd = fd.dup();
   15689                     } catch (IOException e) {
   15690                         fd = null;
   15691                     }
   15692                     proc.thread.profilerControl(start, path, fd, profileType);
   15693                     fd = null;
   15694                     mProfileFd = null;
   15695                 } else {
   15696                     stopProfilerLocked(proc, path, profileType);
   15697                     if (fd != null) {
   15698                         try {
   15699                             fd.close();
   15700                         } catch (IOException e) {
   15701                         }
   15702                     }
   15703                 }
   15704 
   15705                 return true;
   15706             }
   15707         } catch (RemoteException e) {
   15708             throw new IllegalStateException("Process disappeared");
   15709         } finally {
   15710             if (fd != null) {
   15711                 try {
   15712                     fd.close();
   15713                 } catch (IOException e) {
   15714                 }
   15715             }
   15716         }
   15717     }
   15718 
   15719     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   15720         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   15721                 userId, true, true, callName, null);
   15722         ProcessRecord proc = null;
   15723         try {
   15724             int pid = Integer.parseInt(process);
   15725             synchronized (mPidsSelfLocked) {
   15726                 proc = mPidsSelfLocked.get(pid);
   15727             }
   15728         } catch (NumberFormatException e) {
   15729         }
   15730 
   15731         if (proc == null) {
   15732             ArrayMap<String, SparseArray<ProcessRecord>> all
   15733                     = mProcessNames.getMap();
   15734             SparseArray<ProcessRecord> procs = all.get(process);
   15735             if (procs != null && procs.size() > 0) {
   15736                 proc = procs.valueAt(0);
   15737                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   15738                     for (int i=1; i<procs.size(); i++) {
   15739                         ProcessRecord thisProc = procs.valueAt(i);
   15740                         if (thisProc.userId == userId) {
   15741                             proc = thisProc;
   15742                             break;
   15743                         }
   15744                     }
   15745                 }
   15746             }
   15747         }
   15748 
   15749         return proc;
   15750     }
   15751 
   15752     public boolean dumpHeap(String process, int userId, boolean managed,
   15753             String path, ParcelFileDescriptor fd) throws RemoteException {
   15754 
   15755         try {
   15756             synchronized (this) {
   15757                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15758                 // its own permission (same as profileControl).
   15759                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15760                         != PackageManager.PERMISSION_GRANTED) {
   15761                     throw new SecurityException("Requires permission "
   15762                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15763                 }
   15764 
   15765                 if (fd == null) {
   15766                     throw new IllegalArgumentException("null fd");
   15767                 }
   15768 
   15769                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   15770                 if (proc == null || proc.thread == null) {
   15771                     throw new IllegalArgumentException("Unknown process: " + process);
   15772                 }
   15773 
   15774                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   15775                 if (!isDebuggable) {
   15776                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   15777                         throw new SecurityException("Process not debuggable: " + proc);
   15778                     }
   15779                 }
   15780 
   15781                 proc.thread.dumpHeap(managed, path, fd);
   15782                 fd = null;
   15783                 return true;
   15784             }
   15785         } catch (RemoteException e) {
   15786             throw new IllegalStateException("Process disappeared");
   15787         } finally {
   15788             if (fd != null) {
   15789                 try {
   15790                     fd.close();
   15791                 } catch (IOException e) {
   15792                 }
   15793             }
   15794         }
   15795     }
   15796 
   15797     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   15798     public void monitor() {
   15799         synchronized (this) { }
   15800     }
   15801 
   15802     void onCoreSettingsChange(Bundle settings) {
   15803         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   15804             ProcessRecord processRecord = mLruProcesses.get(i);
   15805             try {
   15806                 if (processRecord.thread != null) {
   15807                     processRecord.thread.setCoreSettings(settings);
   15808                 }
   15809             } catch (RemoteException re) {
   15810                 /* ignore */
   15811             }
   15812         }
   15813     }
   15814 
   15815     // Multi-user methods
   15816 
   15817     @Override
   15818     public boolean switchUser(final int userId) {
   15819         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   15820                 != PackageManager.PERMISSION_GRANTED) {
   15821             String msg = "Permission Denial: switchUser() from pid="
   15822                     + Binder.getCallingPid()
   15823                     + ", uid=" + Binder.getCallingUid()
   15824                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   15825             Slog.w(TAG, msg);
   15826             throw new SecurityException(msg);
   15827         }
   15828 
   15829         final long ident = Binder.clearCallingIdentity();
   15830         try {
   15831             synchronized (this) {
   15832                 final int oldUserId = mCurrentUserId;
   15833                 if (oldUserId == userId) {
   15834                     return true;
   15835                 }
   15836 
   15837                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   15838                 if (userInfo == null) {
   15839                     Slog.w(TAG, "No user info for user #" + userId);
   15840                     return false;
   15841                 }
   15842 
   15843                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   15844                         R.anim.screen_user_enter);
   15845 
   15846                 boolean needStart = false;
   15847 
   15848                 // If the user we are switching to is not currently started, then
   15849                 // we need to start it now.
   15850                 if (mStartedUsers.get(userId) == null) {
   15851                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   15852                     updateStartedUserArrayLocked();
   15853                     needStart = true;
   15854                 }
   15855 
   15856                 mCurrentUserId = userId;
   15857                 final Integer userIdInt = Integer.valueOf(userId);
   15858                 mUserLru.remove(userIdInt);
   15859                 mUserLru.add(userIdInt);
   15860 
   15861                 mWindowManager.setCurrentUser(userId);
   15862 
   15863                 // Once the internal notion of the active user has switched, we lock the device
   15864                 // with the option to show the user switcher on the keyguard.
   15865                 mWindowManager.lockNow(null);
   15866 
   15867                 final UserStartedState uss = mStartedUsers.get(userId);
   15868 
   15869                 // Make sure user is in the started state.  If it is currently
   15870                 // stopping, we need to knock that off.
   15871                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   15872                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   15873                     // so we can just fairly silently bring the user back from
   15874                     // the almost-dead.
   15875                     uss.mState = UserStartedState.STATE_RUNNING;
   15876                     updateStartedUserArrayLocked();
   15877                     needStart = true;
   15878                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   15879                     // This means ACTION_SHUTDOWN has been sent, so we will
   15880                     // need to treat this as a new boot of the user.
   15881                     uss.mState = UserStartedState.STATE_BOOTING;
   15882                     updateStartedUserArrayLocked();
   15883                     needStart = true;
   15884                 }
   15885 
   15886                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   15887                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   15888                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   15889                         oldUserId, userId, uss));
   15890                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   15891                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   15892                 if (needStart) {
   15893                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   15894                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   15895                             | Intent.FLAG_RECEIVER_FOREGROUND);
   15896                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   15897                     broadcastIntentLocked(null, null, intent,
   15898                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   15899                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   15900                 }
   15901 
   15902                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   15903                     if (userId != 0) {
   15904                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   15905                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   15906                         broadcastIntentLocked(null, null, intent, null,
   15907                                 new IIntentReceiver.Stub() {
   15908                                     public void performReceive(Intent intent, int resultCode,
   15909                                             String data, Bundle extras, boolean ordered,
   15910                                             boolean sticky, int sendingUser) {
   15911                                         userInitialized(uss, userId);
   15912                                     }
   15913                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   15914                                 true, false, MY_PID, Process.SYSTEM_UID,
   15915                                 userId);
   15916                         uss.initializing = true;
   15917                     } else {
   15918                         getUserManagerLocked().makeInitialized(userInfo.id);
   15919                     }
   15920                 }
   15921 
   15922                 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
   15923                 if (homeInFront) {
   15924                     startHomeActivityLocked(userId);
   15925                 } else {
   15926                     mStackSupervisor.resumeTopActivitiesLocked();
   15927                 }
   15928 
   15929                 EventLogTags.writeAmSwitchUser(userId);
   15930                 getUserManagerLocked().userForeground(userId);
   15931                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
   15932                 if (needStart) {
   15933                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   15934                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   15935                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   15936                     broadcastIntentLocked(null, null, intent,
   15937                             null, new IIntentReceiver.Stub() {
   15938                                 @Override
   15939                                 public void performReceive(Intent intent, int resultCode, String data,
   15940                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   15941                                         throws RemoteException {
   15942                                 }
   15943                             }, 0, null, null,
   15944                             android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   15945                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   15946                 }
   15947             }
   15948         } finally {
   15949             Binder.restoreCallingIdentity(ident);
   15950         }
   15951 
   15952         return true;
   15953     }
   15954 
   15955     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   15956         long ident = Binder.clearCallingIdentity();
   15957         try {
   15958             Intent intent;
   15959             if (oldUserId >= 0) {
   15960                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   15961                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   15962                         | Intent.FLAG_RECEIVER_FOREGROUND);
   15963                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
   15964                 broadcastIntentLocked(null, null, intent,
   15965                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   15966                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
   15967             }
   15968             if (newUserId >= 0) {
   15969                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   15970                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   15971                         | Intent.FLAG_RECEIVER_FOREGROUND);
   15972                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   15973                 broadcastIntentLocked(null, null, intent,
   15974                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   15975                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
   15976                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   15977                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   15978                         | Intent.FLAG_RECEIVER_FOREGROUND);
   15979                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   15980                 broadcastIntentLocked(null, null, intent,
   15981                         null, null, 0, null, null,
   15982                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   15983                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   15984             }
   15985         } finally {
   15986             Binder.restoreCallingIdentity(ident);
   15987         }
   15988     }
   15989 
   15990     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   15991             final int newUserId) {
   15992         final int N = mUserSwitchObservers.beginBroadcast();
   15993         if (N > 0) {
   15994             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   15995                 int mCount = 0;
   15996                 @Override
   15997                 public void sendResult(Bundle data) throws RemoteException {
   15998                     synchronized (ActivityManagerService.this) {
   15999                         if (mCurUserSwitchCallback == this) {
   16000                             mCount++;
   16001                             if (mCount == N) {
   16002                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16003                             }
   16004                         }
   16005                     }
   16006                 }
   16007             };
   16008             synchronized (this) {
   16009                 uss.switching = true;
   16010                 mCurUserSwitchCallback = callback;
   16011             }
   16012             for (int i=0; i<N; i++) {
   16013                 try {
   16014                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   16015                             newUserId, callback);
   16016                 } catch (RemoteException e) {
   16017                 }
   16018             }
   16019         } else {
   16020             synchronized (this) {
   16021                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16022             }
   16023         }
   16024         mUserSwitchObservers.finishBroadcast();
   16025     }
   16026 
   16027     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16028         synchronized (this) {
   16029             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   16030             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16031         }
   16032     }
   16033 
   16034     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   16035         mCurUserSwitchCallback = null;
   16036         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   16037         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   16038                 oldUserId, newUserId, uss));
   16039     }
   16040 
   16041     void userInitialized(UserStartedState uss, int newUserId) {
   16042         completeSwitchAndInitalize(uss, newUserId, true, false);
   16043     }
   16044 
   16045     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16046         completeSwitchAndInitalize(uss, newUserId, false, true);
   16047     }
   16048 
   16049     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   16050             boolean clearInitializing, boolean clearSwitching) {
   16051         boolean unfrozen = false;
   16052         synchronized (this) {
   16053             if (clearInitializing) {
   16054                 uss.initializing = false;
   16055                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   16056             }
   16057             if (clearSwitching) {
   16058                 uss.switching = false;
   16059             }
   16060             if (!uss.switching && !uss.initializing) {
   16061                 mWindowManager.stopFreezingScreen();
   16062                 unfrozen = true;
   16063             }
   16064         }
   16065         if (unfrozen) {
   16066             final int N = mUserSwitchObservers.beginBroadcast();
   16067             for (int i=0; i<N; i++) {
   16068                 try {
   16069                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   16070                 } catch (RemoteException e) {
   16071                 }
   16072             }
   16073             mUserSwitchObservers.finishBroadcast();
   16074         }
   16075     }
   16076 
   16077     void finishUserSwitch(UserStartedState uss) {
   16078         synchronized (this) {
   16079             if (uss.mState == UserStartedState.STATE_BOOTING
   16080                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   16081                 uss.mState = UserStartedState.STATE_RUNNING;
   16082                 final int userId = uss.mHandle.getIdentifier();
   16083                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   16084                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16085                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   16086                 broadcastIntentLocked(null, null, intent,
   16087                         null, null, 0, null, null,
   16088                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   16089                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   16090             }
   16091             int num = mUserLru.size();
   16092             int i = 0;
   16093             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   16094                 Integer oldUserId = mUserLru.get(i);
   16095                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   16096                 if (oldUss == null) {
   16097                     // Shouldn't happen, but be sane if it does.
   16098                     mUserLru.remove(i);
   16099                     num--;
   16100                     continue;
   16101                 }
   16102                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   16103                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   16104                     // This user is already stopping, doesn't count.
   16105                     num--;
   16106                     i++;
   16107                     continue;
   16108                 }
   16109                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   16110                     // Owner and current can't be stopped, but count as running.
   16111                     i++;
   16112                     continue;
   16113                 }
   16114                 // This is a user to be stopped.
   16115                 stopUserLocked(oldUserId, null);
   16116                 num--;
   16117                 i++;
   16118             }
   16119         }
   16120     }
   16121 
   16122     @Override
   16123     public int stopUser(final int userId, final IStopUserCallback callback) {
   16124         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16125                 != PackageManager.PERMISSION_GRANTED) {
   16126             String msg = "Permission Denial: switchUser() from pid="
   16127                     + Binder.getCallingPid()
   16128                     + ", uid=" + Binder.getCallingUid()
   16129                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16130             Slog.w(TAG, msg);
   16131             throw new SecurityException(msg);
   16132         }
   16133         if (userId <= 0) {
   16134             throw new IllegalArgumentException("Can't stop primary user " + userId);
   16135         }
   16136         synchronized (this) {
   16137             return stopUserLocked(userId, callback);
   16138         }
   16139     }
   16140 
   16141     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   16142         if (mCurrentUserId == userId) {
   16143             return ActivityManager.USER_OP_IS_CURRENT;
   16144         }
   16145 
   16146         final UserStartedState uss = mStartedUsers.get(userId);
   16147         if (uss == null) {
   16148             // User is not started, nothing to do...  but we do need to
   16149             // callback if requested.
   16150             if (callback != null) {
   16151                 mHandler.post(new Runnable() {
   16152                     @Override
   16153                     public void run() {
   16154                         try {
   16155                             callback.userStopped(userId);
   16156                         } catch (RemoteException e) {
   16157                         }
   16158                     }
   16159                 });
   16160             }
   16161             return ActivityManager.USER_OP_SUCCESS;
   16162         }
   16163 
   16164         if (callback != null) {
   16165             uss.mStopCallbacks.add(callback);
   16166         }
   16167 
   16168         if (uss.mState != UserStartedState.STATE_STOPPING
   16169                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16170             uss.mState = UserStartedState.STATE_STOPPING;
   16171             updateStartedUserArrayLocked();
   16172 
   16173             long ident = Binder.clearCallingIdentity();
   16174             try {
   16175                 // We are going to broadcast ACTION_USER_STOPPING and then
   16176                 // once that is done send a final ACTION_SHUTDOWN and then
   16177                 // stop the user.
   16178                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   16179                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16180                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16181                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   16182                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   16183                 // This is the result receiver for the final shutdown broadcast.
   16184                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   16185                     @Override
   16186                     public void performReceive(Intent intent, int resultCode, String data,
   16187                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   16188                         finishUserStop(uss);
   16189                     }
   16190                 };
   16191                 // This is the result receiver for the initial stopping broadcast.
   16192                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   16193                     @Override
   16194                     public void performReceive(Intent intent, int resultCode, String data,
   16195                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   16196                         // On to the next.
   16197                         synchronized (ActivityManagerService.this) {
   16198                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   16199                                 // Whoops, we are being started back up.  Abort, abort!
   16200                                 return;
   16201                             }
   16202                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   16203                         }
   16204                         broadcastIntentLocked(null, null, shutdownIntent,
   16205                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   16206                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   16207                     }
   16208                 };
   16209                 // Kick things off.
   16210                 broadcastIntentLocked(null, null, stoppingIntent,
   16211                         null, stoppingReceiver, 0, null, null,
   16212                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   16213                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16214             } finally {
   16215                 Binder.restoreCallingIdentity(ident);
   16216             }
   16217         }
   16218 
   16219         return ActivityManager.USER_OP_SUCCESS;
   16220     }
   16221 
   16222     void finishUserStop(UserStartedState uss) {
   16223         final int userId = uss.mHandle.getIdentifier();
   16224         boolean stopped;
   16225         ArrayList<IStopUserCallback> callbacks;
   16226         synchronized (this) {
   16227             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   16228             if (mStartedUsers.get(userId) != uss) {
   16229                 stopped = false;
   16230             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16231                 stopped = false;
   16232             } else {
   16233                 stopped = true;
   16234                 // User can no longer run.
   16235                 mStartedUsers.remove(userId);
   16236                 mUserLru.remove(Integer.valueOf(userId));
   16237                 updateStartedUserArrayLocked();
   16238 
   16239                 // Clean up all state and processes associated with the user.
   16240                 // Kill all the processes for the user.
   16241                 forceStopUserLocked(userId, "finish user");
   16242             }
   16243         }
   16244 
   16245         for (int i=0; i<callbacks.size(); i++) {
   16246             try {
   16247                 if (stopped) callbacks.get(i).userStopped(userId);
   16248                 else callbacks.get(i).userStopAborted(userId);
   16249             } catch (RemoteException e) {
   16250             }
   16251         }
   16252 
   16253         mStackSupervisor.removeUserLocked(userId);
   16254     }
   16255 
   16256     @Override
   16257     public UserInfo getCurrentUser() {
   16258         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16259                 != PackageManager.PERMISSION_GRANTED) && (
   16260                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16261                 != PackageManager.PERMISSION_GRANTED)) {
   16262             String msg = "Permission Denial: getCurrentUser() from pid="
   16263                     + Binder.getCallingPid()
   16264                     + ", uid=" + Binder.getCallingUid()
   16265                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16266             Slog.w(TAG, msg);
   16267             throw new SecurityException(msg);
   16268         }
   16269         synchronized (this) {
   16270             return getUserManagerLocked().getUserInfo(mCurrentUserId);
   16271         }
   16272     }
   16273 
   16274     int getCurrentUserIdLocked() {
   16275         return mCurrentUserId;
   16276     }
   16277 
   16278     @Override
   16279     public boolean isUserRunning(int userId, boolean orStopped) {
   16280         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16281                 != PackageManager.PERMISSION_GRANTED) {
   16282             String msg = "Permission Denial: isUserRunning() from pid="
   16283                     + Binder.getCallingPid()
   16284                     + ", uid=" + Binder.getCallingUid()
   16285                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16286             Slog.w(TAG, msg);
   16287             throw new SecurityException(msg);
   16288         }
   16289         synchronized (this) {
   16290             return isUserRunningLocked(userId, orStopped);
   16291         }
   16292     }
   16293 
   16294     boolean isUserRunningLocked(int userId, boolean orStopped) {
   16295         UserStartedState state = mStartedUsers.get(userId);
   16296         if (state == null) {
   16297             return false;
   16298         }
   16299         if (orStopped) {
   16300             return true;
   16301         }
   16302         return state.mState != UserStartedState.STATE_STOPPING
   16303                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   16304     }
   16305 
   16306     @Override
   16307     public int[] getRunningUserIds() {
   16308         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16309                 != PackageManager.PERMISSION_GRANTED) {
   16310             String msg = "Permission Denial: isUserRunning() from pid="
   16311                     + Binder.getCallingPid()
   16312                     + ", uid=" + Binder.getCallingUid()
   16313                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16314             Slog.w(TAG, msg);
   16315             throw new SecurityException(msg);
   16316         }
   16317         synchronized (this) {
   16318             return mStartedUserArray;
   16319         }
   16320     }
   16321 
   16322     private void updateStartedUserArrayLocked() {
   16323         int num = 0;
   16324         for (int i=0; i<mStartedUsers.size();  i++) {
   16325             UserStartedState uss = mStartedUsers.valueAt(i);
   16326             // This list does not include stopping users.
   16327             if (uss.mState != UserStartedState.STATE_STOPPING
   16328                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16329                 num++;
   16330             }
   16331         }
   16332         mStartedUserArray = new int[num];
   16333         num = 0;
   16334         for (int i=0; i<mStartedUsers.size();  i++) {
   16335             UserStartedState uss = mStartedUsers.valueAt(i);
   16336             if (uss.mState != UserStartedState.STATE_STOPPING
   16337                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16338                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   16339                 num++;
   16340             }
   16341         }
   16342     }
   16343 
   16344     @Override
   16345     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   16346         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16347                 != PackageManager.PERMISSION_GRANTED) {
   16348             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   16349                     + Binder.getCallingPid()
   16350                     + ", uid=" + Binder.getCallingUid()
   16351                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16352             Slog.w(TAG, msg);
   16353             throw new SecurityException(msg);
   16354         }
   16355 
   16356         mUserSwitchObservers.register(observer);
   16357     }
   16358 
   16359     @Override
   16360     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   16361         mUserSwitchObservers.unregister(observer);
   16362     }
   16363 
   16364     private boolean userExists(int userId) {
   16365         if (userId == 0) {
   16366             return true;
   16367         }
   16368         UserManagerService ums = getUserManagerLocked();
   16369         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   16370     }
   16371 
   16372     int[] getUsersLocked() {
   16373         UserManagerService ums = getUserManagerLocked();
   16374         return ums != null ? ums.getUserIds() : new int[] { 0 };
   16375     }
   16376 
   16377     UserManagerService getUserManagerLocked() {
   16378         if (mUserManager == null) {
   16379             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   16380             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   16381         }
   16382         return mUserManager;
   16383     }
   16384 
   16385     private void checkValidCaller(int uid, int userId) {
   16386         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
   16387 
   16388         throw new SecurityException("Caller uid=" + uid
   16389                 + " is not privileged to communicate with user=" + userId);
   16390     }
   16391 
   16392     private int applyUserId(int uid, int userId) {
   16393         return UserHandle.getUid(userId, uid);
   16394     }
   16395 
   16396     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   16397         if (info == null) return null;
   16398         ApplicationInfo newInfo = new ApplicationInfo(info);
   16399         newInfo.uid = applyUserId(info.uid, userId);
   16400         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   16401                 + info.packageName;
   16402         return newInfo;
   16403     }
   16404 
   16405     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   16406         if (aInfo == null
   16407                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   16408             return aInfo;
   16409         }
   16410 
   16411         ActivityInfo info = new ActivityInfo(aInfo);
   16412         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   16413         return info;
   16414     }
   16415 }
   16416