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 com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
     25 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
     26 import static org.xmlpull.v1.XmlPullParser.START_TAG;
     27 
     28 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
     29 
     30 import android.app.AppOpsManager;
     31 import android.appwidget.AppWidgetManager;
     32 import android.util.ArrayMap;
     33 import com.android.internal.R;
     34 import com.android.internal.annotations.GuardedBy;
     35 import com.android.internal.app.IAppOpsService;
     36 import com.android.internal.app.ProcessStats;
     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_LRU = localLOGV || false;
    221     static final boolean DEBUG_PAUSE = localLOGV || false;
    222     static final boolean DEBUG_POWER = localLOGV || false;
    223     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
    224     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
    225     static final boolean DEBUG_PROCESSES = localLOGV || false;
    226     static final boolean DEBUG_PROVIDER = localLOGV || false;
    227     static final boolean DEBUG_RESULTS = localLOGV || false;
    228     static final boolean DEBUG_SERVICE = localLOGV || false;
    229     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
    230     static final boolean DEBUG_STACK = localLOGV || false;
    231     static final boolean DEBUG_SWITCH = localLOGV || false;
    232     static final boolean DEBUG_TASKS = localLOGV || false;
    233     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
    234     static final boolean DEBUG_TRANSITION = localLOGV || false;
    235     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
    236     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
    237     static final boolean DEBUG_VISBILITY = localLOGV || false;
    238     static final boolean DEBUG_PSS = localLOGV || false;
    239     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
    240     static final boolean VALIDATE_TOKENS = false;
    241     static final boolean SHOW_ACTIVITY_START_TIME = true;
    242 
    243     // Control over CPU and battery monitoring.
    244     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
    245     static final boolean MONITOR_CPU_USAGE = true;
    246     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
    247     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
    248     static final boolean MONITOR_THREAD_CPU_USAGE = false;
    249 
    250     // The flags that are set for all calls we make to the package manager.
    251     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
    252 
    253     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    254 
    255     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
    256 
    257     // Maximum number of recent tasks that we can remember.
    258     static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
    259 
    260     // Amount of time after a call to stopAppSwitches() during which we will
    261     // prevent further untrusted switches from happening.
    262     static final long APP_SWITCH_DELAY_TIME = 5*1000;
    263 
    264     // How long we wait for a launched process to attach to the activity manager
    265     // before we decide it's never going to come up for real.
    266     static final int PROC_START_TIMEOUT = 10*1000;
    267 
    268     // How long we wait for a launched process to attach to the activity manager
    269     // before we decide it's never going to come up for real, when the process was
    270     // started with a wrapper for instrumentation (such as Valgrind) because it
    271     // could take much longer than usual.
    272     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
    273 
    274     // How long to wait after going idle before forcing apps to GC.
    275     static final int GC_TIMEOUT = 5*1000;
    276 
    277     // The minimum amount of time between successive GC requests for a process.
    278     static final int GC_MIN_INTERVAL = 60*1000;
    279 
    280     // The minimum amount of time between successive PSS requests for a process.
    281     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
    282 
    283     // The minimum amount of time between successive PSS requests for a process
    284     // when the request is due to the memory state being lowered.
    285     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
    286 
    287     // The rate at which we check for apps using excessive power -- 15 mins.
    288     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
    289 
    290     // The minimum sample duration we will allow before deciding we have
    291     // enough data on wake locks to start killing things.
    292     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    293 
    294     // The minimum sample duration we will allow before deciding we have
    295     // enough data on CPU usage to start killing things.
    296     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
    297 
    298     // How long we allow a receiver to run before giving up on it.
    299     static final int BROADCAST_FG_TIMEOUT = 10*1000;
    300     static final int BROADCAST_BG_TIMEOUT = 60*1000;
    301 
    302     // How long we wait until we timeout on key dispatching.
    303     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
    304 
    305     // How long we wait until we timeout on key dispatching during instrumentation.
    306     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
    307 
    308     // Amount of time we wait for observers to handle a user switch before
    309     // giving up on them and unfreezing the screen.
    310     static final int USER_SWITCH_TIMEOUT = 2*1000;
    311 
    312     // Maximum number of users we allow to be running at a time.
    313     static final int MAX_RUNNING_USERS = 3;
    314 
    315     // How long to wait in getAssistContextExtras for the activity and foreground services
    316     // to respond with the result.
    317     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
    318 
    319     // Maximum number of persisted Uri grants a package is allowed
    320     static final int MAX_PERSISTED_URI_GRANTS = 128;
    321 
    322     static final int MY_PID = Process.myPid();
    323 
    324     static final String[] EMPTY_STRING_ARRAY = new String[0];
    325 
    326     // How many bytes to write into the dropbox log before truncating
    327     static final int DROPBOX_MAX_SIZE = 256 * 1024;
    328 
    329     /** Run all ActivityStacks through this */
    330     ActivityStackSupervisor mStackSupervisor;
    331 
    332     public IntentFirewall mIntentFirewall;
    333 
    334     private final boolean mHeadless;
    335 
    336     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
    337     // default actuion automatically.  Important for devices without direct input
    338     // devices.
    339     private boolean mShowDialogs = true;
    340 
    341     /**
    342      * Description of a request to start a new activity, which has been held
    343      * due to app switches being disabled.
    344      */
    345     static class PendingActivityLaunch {
    346         final ActivityRecord r;
    347         final ActivityRecord sourceRecord;
    348         final int startFlags;
    349         final ActivityStack stack;
    350 
    351         PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
    352                 int _startFlags, ActivityStack _stack) {
    353             r = _r;
    354             sourceRecord = _sourceRecord;
    355             startFlags = _startFlags;
    356             stack = _stack;
    357         }
    358     }
    359 
    360     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
    361             = new ArrayList<PendingActivityLaunch>();
    362 
    363     BroadcastQueue mFgBroadcastQueue;
    364     BroadcastQueue mBgBroadcastQueue;
    365     // Convenient for easy iteration over the queues. Foreground is first
    366     // so that dispatch of foreground broadcasts gets precedence.
    367     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
    368 
    369     BroadcastQueue broadcastQueueForIntent(Intent intent) {
    370         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
    371         if (DEBUG_BACKGROUND_BROADCAST) {
    372             Slog.i(TAG, "Broadcast intent " + intent + " on "
    373                     + (isFg ? "foreground" : "background")
    374                     + " queue");
    375         }
    376         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    377     }
    378 
    379     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
    380         for (BroadcastQueue queue : mBroadcastQueues) {
    381             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
    382             if (r != null) {
    383                 return r;
    384             }
    385         }
    386         return null;
    387     }
    388 
    389     /**
    390      * Activity we have told the window manager to have key focus.
    391      */
    392     ActivityRecord mFocusedActivity = null;
    393 
    394     /**
    395      * List of intents that were used to start the most recent tasks.
    396      */
    397     private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
    398 
    399     public class PendingAssistExtras extends Binder implements Runnable {
    400         public final ActivityRecord activity;
    401         public boolean haveResult = false;
    402         public Bundle result = null;
    403         public PendingAssistExtras(ActivityRecord _activity) {
    404             activity = _activity;
    405         }
    406         @Override
    407         public void run() {
    408             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
    409             synchronized (this) {
    410                 haveResult = true;
    411                 notifyAll();
    412             }
    413         }
    414     }
    415 
    416     final ArrayList<PendingAssistExtras> mPendingAssistExtras
    417             = new ArrayList<PendingAssistExtras>();
    418 
    419     /**
    420      * Process management.
    421      */
    422     final ProcessList mProcessList = new ProcessList();
    423 
    424     /**
    425      * All of the applications we currently have running organized by name.
    426      * The keys are strings of the application package name (as
    427      * returned by the package manager), and the keys are ApplicationRecord
    428      * objects.
    429      */
    430     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
    431 
    432     /**
    433      * Tracking long-term execution of processes to look for abuse and other
    434      * bad app behavior.
    435      */
    436     final ProcessStatsService mProcessStats;
    437 
    438     /**
    439      * The currently running isolated processes.
    440      */
    441     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
    442 
    443     /**
    444      * Counter for assigning isolated process uids, to avoid frequently reusing the
    445      * same ones.
    446      */
    447     int mNextIsolatedProcessUid = 0;
    448 
    449     /**
    450      * The currently running heavy-weight process, if any.
    451      */
    452     ProcessRecord mHeavyWeightProcess = null;
    453 
    454     /**
    455      * The last time that various processes have crashed.
    456      */
    457     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
    458 
    459     /**
    460      * Information about a process that is currently marked as bad.
    461      */
    462     static final class BadProcessInfo {
    463         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
    464             this.time = time;
    465             this.shortMsg = shortMsg;
    466             this.longMsg = longMsg;
    467             this.stack = stack;
    468         }
    469 
    470         final long time;
    471         final String shortMsg;
    472         final String longMsg;
    473         final String stack;
    474     }
    475 
    476     /**
    477      * Set of applications that we consider to be bad, and will reject
    478      * incoming broadcasts from (which the user has no control over).
    479      * Processes are added to this set when they have crashed twice within
    480      * a minimum amount of time; they are removed from it when they are
    481      * later restarted (hopefully due to some user action).  The value is the
    482      * time it was added to the list.
    483      */
    484     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
    485 
    486     /**
    487      * All of the processes we currently have running organized by pid.
    488      * The keys are the pid running the application.
    489      *
    490      * <p>NOTE: This object is protected by its own lock, NOT the global
    491      * activity manager lock!
    492      */
    493     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    494 
    495     /**
    496      * All of the processes that have been forced to be foreground.  The key
    497      * is the pid of the caller who requested it (we hold a death
    498      * link on it).
    499      */
    500     abstract class ForegroundToken implements IBinder.DeathRecipient {
    501         int pid;
    502         IBinder token;
    503     }
    504     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
    505 
    506     /**
    507      * List of records for processes that someone had tried to start before the
    508      * system was ready.  We don't start them at that point, but ensure they
    509      * are started by the time booting is complete.
    510      */
    511     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
    512 
    513     /**
    514      * List of persistent applications that are in the process
    515      * of being started.
    516      */
    517     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
    518 
    519     /**
    520      * Processes that are being forcibly torn down.
    521      */
    522     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    523 
    524     /**
    525      * List of running applications, sorted by recent usage.
    526      * The first entry in the list is the least recently used.
    527      */
    528     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    529 
    530     /**
    531      * Where in mLruProcesses that the processes hosting activities start.
    532      */
    533     int mLruProcessActivityStart = 0;
    534 
    535     /**
    536      * Where in mLruProcesses that the processes hosting services start.
    537      * This is after (lower index) than mLruProcessesActivityStart.
    538      */
    539     int mLruProcessServiceStart = 0;
    540 
    541     /**
    542      * List of processes that should gc as soon as things are idle.
    543      */
    544     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
    545 
    546     /**
    547      * Processes we want to collect PSS data from.
    548      */
    549     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
    550 
    551     /**
    552      * Last time we requested PSS data of all processes.
    553      */
    554     long mLastFullPssTime = SystemClock.uptimeMillis();
    555 
    556     /**
    557      * This is the process holding what we currently consider to be
    558      * the "home" activity.
    559      */
    560     ProcessRecord mHomeProcess;
    561 
    562     /**
    563      * This is the process holding the activity the user last visited that
    564      * is in a different process from the one they are currently in.
    565      */
    566     ProcessRecord mPreviousProcess;
    567 
    568     /**
    569      * The time at which the previous process was last visible.
    570      */
    571     long mPreviousProcessVisibleTime;
    572 
    573     /**
    574      * Which uses have been started, so are allowed to run code.
    575      */
    576     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
    577 
    578     /**
    579      * LRU list of history of current users.  Most recently current is at the end.
    580      */
    581     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
    582 
    583     /**
    584      * Constant array of the users that are currently started.
    585      */
    586     int[] mStartedUserArray = new int[] { 0 };
    587 
    588     /**
    589      * Registered observers of the user switching mechanics.
    590      */
    591     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
    592             = new RemoteCallbackList<IUserSwitchObserver>();
    593 
    594     /**
    595      * Currently active user switch.
    596      */
    597     Object mCurUserSwitchCallback;
    598 
    599     /**
    600      * Packages that the user has asked to have run in screen size
    601      * compatibility mode instead of filling the screen.
    602      */
    603     final CompatModePackages mCompatModePackages;
    604 
    605     /**
    606      * Set of IntentSenderRecord objects that are currently active.
    607      */
    608     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
    609             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
    610 
    611     /**
    612      * Fingerprints (hashCode()) of stack traces that we've
    613      * already logged DropBox entries for.  Guarded by itself.  If
    614      * something (rogue user app) forces this over
    615      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
    616      */
    617     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
    618     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
    619 
    620     /**
    621      * Strict Mode background batched logging state.
    622      *
    623      * The string buffer is guarded by itself, and its lock is also
    624      * used to determine if another batched write is already
    625      * in-flight.
    626      */
    627     private final StringBuilder mStrictModeBuffer = new StringBuilder();
    628 
    629     /**
    630      * Keeps track of all IIntentReceivers that have been registered for
    631      * broadcasts.  Hash keys are the receiver IBinder, hash value is
    632      * a ReceiverList.
    633      */
    634     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
    635             new HashMap<IBinder, ReceiverList>();
    636 
    637     /**
    638      * Resolver for broadcast intents to registered receivers.
    639      * Holds BroadcastFilter (subclass of IntentFilter).
    640      */
    641     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
    642             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
    643         @Override
    644         protected boolean allowFilterResult(
    645                 BroadcastFilter filter, List<BroadcastFilter> dest) {
    646             IBinder target = filter.receiverList.receiver.asBinder();
    647             for (int i=dest.size()-1; i>=0; i--) {
    648                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
    649                     return false;
    650                 }
    651             }
    652             return true;
    653         }
    654 
    655         @Override
    656         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
    657             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
    658                     || userId == filter.owningUserId) {
    659                 return super.newResult(filter, match, userId);
    660             }
    661             return null;
    662         }
    663 
    664         @Override
    665         protected BroadcastFilter[] newArray(int size) {
    666             return new BroadcastFilter[size];
    667         }
    668 
    669         @Override
    670         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
    671             return packageName.equals(filter.packageName);
    672         }
    673     };
    674 
    675     /**
    676      * State of all active sticky broadcasts per user.  Keys are the action of the
    677      * sticky Intent, values are an ArrayList of all broadcasted intents with
    678      * that action (which should usually be one).  The SparseArray is keyed
    679      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
    680      * for stickies that are sent to all users.
    681      */
    682     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
    683             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
    684 
    685     final ActiveServices mServices;
    686 
    687     /**
    688      * Backup/restore process management
    689      */
    690     String mBackupAppName = null;
    691     BackupRecord mBackupTarget = null;
    692 
    693     /**
    694      * List of PendingThumbnailsRecord objects of clients who are still
    695      * waiting to receive all of the thumbnails for a task.
    696      */
    697     final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
    698             new ArrayList<PendingThumbnailsRecord>();
    699 
    700     final ProviderMap mProviderMap;
    701 
    702     /**
    703      * List of content providers who have clients waiting for them.  The
    704      * application is currently being launched and the provider will be
    705      * removed from this list once it is published.
    706      */
    707     final ArrayList<ContentProviderRecord> mLaunchingProviders
    708             = new ArrayList<ContentProviderRecord>();
    709 
    710     /**
    711      * File storing persisted {@link #mGrantedUriPermissions}.
    712      */
    713     private final AtomicFile mGrantFile;
    714 
    715     /** XML constants used in {@link #mGrantFile} */
    716     private static final String TAG_URI_GRANTS = "uri-grants";
    717     private static final String TAG_URI_GRANT = "uri-grant";
    718     private static final String ATTR_USER_HANDLE = "userHandle";
    719     private static final String ATTR_SOURCE_PKG = "sourcePkg";
    720     private static final String ATTR_TARGET_PKG = "targetPkg";
    721     private static final String ATTR_URI = "uri";
    722     private static final String ATTR_MODE_FLAGS = "modeFlags";
    723     private static final String ATTR_CREATED_TIME = "createdTime";
    724 
    725     /**
    726      * Global set of specific {@link Uri} permissions that have been granted.
    727      * This optimized lookup structure maps from {@link UriPermission#targetUid}
    728      * to {@link UriPermission#uri} to {@link UriPermission}.
    729      */
    730     @GuardedBy("this")
    731     private final SparseArray<ArrayMap<Uri, UriPermission>>
    732             mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
    733 
    734     CoreSettingsObserver mCoreSettingsObserver;
    735 
    736     /**
    737      * Thread-local storage used to carry caller permissions over through
    738      * indirect content-provider access.
    739      */
    740     private class Identity {
    741         public int pid;
    742         public int uid;
    743 
    744         Identity(int _pid, int _uid) {
    745             pid = _pid;
    746             uid = _uid;
    747         }
    748     }
    749 
    750     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
    751 
    752     /**
    753      * All information we have collected about the runtime performance of
    754      * any user id that can impact battery performance.
    755      */
    756     final BatteryStatsService mBatteryStatsService;
    757 
    758     /**
    759      * Information about component usage
    760      */
    761     final UsageStatsService mUsageStatsService;
    762 
    763     /**
    764      * Information about and control over application operations
    765      */
    766     final AppOpsService mAppOpsService;
    767 
    768     /**
    769      * Current configuration information.  HistoryRecord objects are given
    770      * a reference to this object to indicate which configuration they are
    771      * currently running in, so this object must be kept immutable.
    772      */
    773     Configuration mConfiguration = new Configuration();
    774 
    775     /**
    776      * Current sequencing integer of the configuration, for skipping old
    777      * configurations.
    778      */
    779     int mConfigurationSeq = 0;
    780 
    781     /**
    782      * Hardware-reported OpenGLES version.
    783      */
    784     final int GL_ES_VERSION;
    785 
    786     /**
    787      * List of initialization arguments to pass to all processes when binding applications to them.
    788      * For example, references to the commonly used services.
    789      */
    790     HashMap<String, IBinder> mAppBindArgs;
    791 
    792     /**
    793      * Temporary to avoid allocations.  Protected by main lock.
    794      */
    795     final StringBuilder mStringBuilder = new StringBuilder(256);
    796 
    797     /**
    798      * Used to control how we initialize the service.
    799      */
    800     boolean mStartRunning = false;
    801     ComponentName mTopComponent;
    802     String mTopAction;
    803     String mTopData;
    804     boolean mProcessesReady = false;
    805     boolean mSystemReady = false;
    806     boolean mBooting = false;
    807     boolean mWaitingUpdate = false;
    808     boolean mDidUpdate = false;
    809     boolean mOnBattery = false;
    810     boolean mLaunchWarningShown = false;
    811 
    812     Context mContext;
    813 
    814     int mFactoryTest;
    815 
    816     boolean mCheckedForSetup;
    817 
    818     /**
    819      * The time at which we will allow normal application switches again,
    820      * after a call to {@link #stopAppSwitches()}.
    821      */
    822     long mAppSwitchesAllowedTime;
    823 
    824     /**
    825      * This is set to true after the first switch after mAppSwitchesAllowedTime
    826      * is set; any switches after that will clear the time.
    827      */
    828     boolean mDidAppSwitch;
    829 
    830     /**
    831      * Last time (in realtime) at which we checked for power usage.
    832      */
    833     long mLastPowerCheckRealtime;
    834 
    835     /**
    836      * Last time (in uptime) at which we checked for power usage.
    837      */
    838     long mLastPowerCheckUptime;
    839 
    840     /**
    841      * Set while we are wanting to sleep, to prevent any
    842      * activities from being started/resumed.
    843      */
    844     boolean mSleeping = false;
    845 
    846     /**
    847      * State of external calls telling us if the device is asleep.
    848      */
    849     boolean mWentToSleep = false;
    850 
    851     /**
    852      * State of external call telling us if the lock screen is shown.
    853      */
    854     boolean mLockScreenShown = false;
    855 
    856     /**
    857      * Set if we are shutting down the system, similar to sleeping.
    858      */
    859     boolean mShuttingDown = false;
    860 
    861     /**
    862      * Current sequence id for oom_adj computation traversal.
    863      */
    864     int mAdjSeq = 0;
    865 
    866     /**
    867      * Current sequence id for process LRU updating.
    868      */
    869     int mLruSeq = 0;
    870 
    871     /**
    872      * Keep track of the non-cached/empty process we last found, to help
    873      * determine how to distribute cached/empty processes next time.
    874      */
    875     int mNumNonCachedProcs = 0;
    876 
    877     /**
    878      * Keep track of the number of cached hidden procs, to balance oom adj
    879      * distribution between those and empty procs.
    880      */
    881     int mNumCachedHiddenProcs = 0;
    882 
    883     /**
    884      * Keep track of the number of service processes we last found, to
    885      * determine on the next iteration which should be B services.
    886      */
    887     int mNumServiceProcs = 0;
    888     int mNewNumAServiceProcs = 0;
    889     int mNewNumServiceProcs = 0;
    890 
    891     /**
    892      * Allow the current computed overall memory level of the system to go down?
    893      * This is set to false when we are killing processes for reasons other than
    894      * memory management, so that the now smaller process list will not be taken as
    895      * an indication that memory is tighter.
    896      */
    897     boolean mAllowLowerMemLevel = false;
    898 
    899     /**
    900      * The last computed memory level, for holding when we are in a state that
    901      * processes are going away for other reasons.
    902      */
    903     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
    904 
    905     /**
    906      * The last total number of process we have, to determine if changes actually look
    907      * like a shrinking number of process due to lower RAM.
    908      */
    909     int mLastNumProcesses;
    910 
    911     /**
    912      * The uptime of the last time we performed idle maintenance.
    913      */
    914     long mLastIdleTime = SystemClock.uptimeMillis();
    915 
    916     /**
    917      * Total time spent with RAM that has been added in the past since the last idle time.
    918      */
    919     long mLowRamTimeSinceLastIdle = 0;
    920 
    921     /**
    922      * If RAM is currently low, when that horrible situatin started.
    923      */
    924     long mLowRamStartTime = 0;
    925 
    926     /**
    927      * This is set if we had to do a delayed dexopt of an app before launching
    928      * it, to increasing the ANR timeouts in that case.
    929      */
    930     boolean mDidDexOpt;
    931 
    932     String mDebugApp = null;
    933     boolean mWaitForDebugger = false;
    934     boolean mDebugTransient = false;
    935     String mOrigDebugApp = null;
    936     boolean mOrigWaitForDebugger = false;
    937     boolean mAlwaysFinishActivities = false;
    938     IActivityController mController = null;
    939     String mProfileApp = null;
    940     ProcessRecord mProfileProc = null;
    941     String mProfileFile;
    942     ParcelFileDescriptor mProfileFd;
    943     int mProfileType = 0;
    944     boolean mAutoStopProfiler = false;
    945     String mOpenGlTraceApp = null;
    946 
    947     static class ProcessChangeItem {
    948         static final int CHANGE_ACTIVITIES = 1<<0;
    949         static final int CHANGE_IMPORTANCE= 1<<1;
    950         int changes;
    951         int uid;
    952         int pid;
    953         int importance;
    954         boolean foregroundActivities;
    955     }
    956 
    957     final RemoteCallbackList<IProcessObserver> mProcessObservers
    958             = new RemoteCallbackList<IProcessObserver>();
    959     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
    960 
    961     final ArrayList<ProcessChangeItem> mPendingProcessChanges
    962             = new ArrayList<ProcessChangeItem>();
    963     final ArrayList<ProcessChangeItem> mAvailProcessChanges
    964             = new ArrayList<ProcessChangeItem>();
    965 
    966     /**
    967      * Runtime CPU use collection thread.  This object's lock is used to
    968      * protect all related state.
    969      */
    970     final Thread mProcessCpuThread;
    971 
    972     /**
    973      * Used to collect process stats when showing not responding dialog.
    974      * Protected by mProcessCpuThread.
    975      */
    976     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
    977             MONITOR_THREAD_CPU_USAGE);
    978     final AtomicLong mLastCpuTime = new AtomicLong(0);
    979     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
    980 
    981     long mLastWriteTime = 0;
    982 
    983     /**
    984      * Used to retain an update lock when the foreground activity is in
    985      * immersive mode.
    986      */
    987     final UpdateLock mUpdateLock = new UpdateLock("immersive");
    988 
    989     /**
    990      * Set to true after the system has finished booting.
    991      */
    992     boolean mBooted = false;
    993 
    994     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
    995     int mProcessLimitOverride = -1;
    996 
    997     WindowManagerService mWindowManager;
    998 
    999     static ActivityManagerService mSelf;
   1000     static ActivityThread mSystemThread;
   1001 
   1002     int mCurrentUserId = 0;
   1003     private UserManagerService mUserManager;
   1004 
   1005     private final class AppDeathRecipient implements IBinder.DeathRecipient {
   1006         final ProcessRecord mApp;
   1007         final int mPid;
   1008         final IApplicationThread mAppThread;
   1009 
   1010         AppDeathRecipient(ProcessRecord app, int pid,
   1011                 IApplicationThread thread) {
   1012             if (localLOGV) Slog.v(
   1013                 TAG, "New death recipient " + this
   1014                 + " for thread " + thread.asBinder());
   1015             mApp = app;
   1016             mPid = pid;
   1017             mAppThread = thread;
   1018         }
   1019 
   1020         @Override
   1021         public void binderDied() {
   1022             if (localLOGV) Slog.v(
   1023                 TAG, "Death received in " + this
   1024                 + " for thread " + mAppThread.asBinder());
   1025             synchronized(ActivityManagerService.this) {
   1026                 appDiedLocked(mApp, mPid, mAppThread);
   1027             }
   1028         }
   1029     }
   1030 
   1031     static final int SHOW_ERROR_MSG = 1;
   1032     static final int SHOW_NOT_RESPONDING_MSG = 2;
   1033     static final int SHOW_FACTORY_ERROR_MSG = 3;
   1034     static final int UPDATE_CONFIGURATION_MSG = 4;
   1035     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
   1036     static final int WAIT_FOR_DEBUGGER_MSG = 6;
   1037     static final int SERVICE_TIMEOUT_MSG = 12;
   1038     static final int UPDATE_TIME_ZONE = 13;
   1039     static final int SHOW_UID_ERROR_MSG = 14;
   1040     static final int IM_FEELING_LUCKY_MSG = 15;
   1041     static final int PROC_START_TIMEOUT_MSG = 20;
   1042     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
   1043     static final int KILL_APPLICATION_MSG = 22;
   1044     static final int FINALIZE_PENDING_INTENT_MSG = 23;
   1045     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
   1046     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
   1047     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
   1048     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
   1049     static final int CLEAR_DNS_CACHE_MSG = 28;
   1050     static final int UPDATE_HTTP_PROXY_MSG = 29;
   1051     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
   1052     static final int DISPATCH_PROCESSES_CHANGED = 31;
   1053     static final int DISPATCH_PROCESS_DIED = 32;
   1054     static final int REPORT_MEM_USAGE_MSG = 33;
   1055     static final int REPORT_USER_SWITCH_MSG = 34;
   1056     static final int CONTINUE_USER_SWITCH_MSG = 35;
   1057     static final int USER_SWITCH_TIMEOUT_MSG = 36;
   1058     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
   1059     static final int PERSIST_URI_GRANTS_MSG = 38;
   1060     static final int REQUEST_ALL_PSS_MSG = 39;
   1061 
   1062     static final int FIRST_ACTIVITY_STACK_MSG = 100;
   1063     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
   1064     static final int FIRST_COMPAT_MODE_MSG = 300;
   1065     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
   1066 
   1067     AlertDialog mUidAlert;
   1068     CompatModeDialog mCompatModeDialog;
   1069     long mLastMemUsageReportTime = 0;
   1070 
   1071     /**
   1072      * Flag whether the current user is a "monkey", i.e. whether
   1073      * the UI is driven by a UI automation tool.
   1074      */
   1075     private boolean mUserIsMonkey;
   1076 
   1077     final Handler mHandler = new Handler() {
   1078         //public Handler() {
   1079         //    if (localLOGV) Slog.v(TAG, "Handler started!");
   1080         //}
   1081 
   1082         @Override
   1083         public void handleMessage(Message msg) {
   1084             switch (msg.what) {
   1085             case SHOW_ERROR_MSG: {
   1086                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1087                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   1088                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   1089                 synchronized (ActivityManagerService.this) {
   1090                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1091                     AppErrorResult res = (AppErrorResult) data.get("result");
   1092                     if (proc != null && proc.crashDialog != null) {
   1093                         Slog.e(TAG, "App already has crash dialog: " + proc);
   1094                         if (res != null) {
   1095                             res.set(0);
   1096                         }
   1097                         return;
   1098                     }
   1099                     if (!showBackground && UserHandle.getAppId(proc.uid)
   1100                             >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
   1101                             && proc.pid != MY_PID) {
   1102                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
   1103                         if (res != null) {
   1104                             res.set(0);
   1105                         }
   1106                         return;
   1107                     }
   1108                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1109                         Dialog d = new AppErrorDialog(mContext,
   1110                                 ActivityManagerService.this, res, proc);
   1111                         d.show();
   1112                         proc.crashDialog = d;
   1113                     } else {
   1114                         // The device is asleep, so just pretend that the user
   1115                         // saw a crash dialog and hit "force quit".
   1116                         if (res != null) {
   1117                             res.set(0);
   1118                         }
   1119                     }
   1120                 }
   1121 
   1122                 ensureBootCompleted();
   1123             } break;
   1124             case SHOW_NOT_RESPONDING_MSG: {
   1125                 synchronized (ActivityManagerService.this) {
   1126                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1127                     ProcessRecord proc = (ProcessRecord)data.get("app");
   1128                     if (proc != null && proc.anrDialog != null) {
   1129                         Slog.e(TAG, "App already has anr dialog: " + proc);
   1130                         return;
   1131                     }
   1132 
   1133                     Intent intent = new Intent("android.intent.action.ANR");
   1134                     if (!mProcessesReady) {
   1135                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   1136                                 | Intent.FLAG_RECEIVER_FOREGROUND);
   1137                     }
   1138                     broadcastIntentLocked(null, null, intent,
   1139                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   1140                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
   1141 
   1142                     if (mShowDialogs) {
   1143                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
   1144                                 mContext, proc, (ActivityRecord)data.get("activity"),
   1145                                 msg.arg1 != 0);
   1146                         d.show();
   1147                         proc.anrDialog = d;
   1148                     } else {
   1149                         // Just kill the app if there is no dialog to be shown.
   1150                         killAppAtUsersRequest(proc, null);
   1151                     }
   1152                 }
   1153 
   1154                 ensureBootCompleted();
   1155             } break;
   1156             case SHOW_STRICT_MODE_VIOLATION_MSG: {
   1157                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
   1158                 synchronized (ActivityManagerService.this) {
   1159                     ProcessRecord proc = (ProcessRecord) data.get("app");
   1160                     if (proc == null) {
   1161                         Slog.e(TAG, "App not found when showing strict mode dialog.");
   1162                         break;
   1163                     }
   1164                     if (proc.crashDialog != null) {
   1165                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
   1166                         return;
   1167                     }
   1168                     AppErrorResult res = (AppErrorResult) data.get("result");
   1169                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
   1170                         Dialog d = new StrictModeViolationDialog(mContext,
   1171                                 ActivityManagerService.this, res, proc);
   1172                         d.show();
   1173                         proc.crashDialog = d;
   1174                     } else {
   1175                         // The device is asleep, so just pretend that the user
   1176                         // saw a crash dialog and hit "force quit".
   1177                         res.set(0);
   1178                     }
   1179                 }
   1180                 ensureBootCompleted();
   1181             } break;
   1182             case SHOW_FACTORY_ERROR_MSG: {
   1183                 Dialog d = new FactoryErrorDialog(
   1184                     mContext, msg.getData().getCharSequence("msg"));
   1185                 d.show();
   1186                 ensureBootCompleted();
   1187             } break;
   1188             case UPDATE_CONFIGURATION_MSG: {
   1189                 final ContentResolver resolver = mContext.getContentResolver();
   1190                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
   1191             } break;
   1192             case GC_BACKGROUND_PROCESSES_MSG: {
   1193                 synchronized (ActivityManagerService.this) {
   1194                     performAppGcsIfAppropriateLocked();
   1195                 }
   1196             } break;
   1197             case WAIT_FOR_DEBUGGER_MSG: {
   1198                 synchronized (ActivityManagerService.this) {
   1199                     ProcessRecord app = (ProcessRecord)msg.obj;
   1200                     if (msg.arg1 != 0) {
   1201                         if (!app.waitedForDebugger) {
   1202                             Dialog d = new AppWaitingForDebuggerDialog(
   1203                                     ActivityManagerService.this,
   1204                                     mContext, app);
   1205                             app.waitDialog = d;
   1206                             app.waitedForDebugger = true;
   1207                             d.show();
   1208                         }
   1209                     } else {
   1210                         if (app.waitDialog != null) {
   1211                             app.waitDialog.dismiss();
   1212                             app.waitDialog = null;
   1213                         }
   1214                     }
   1215                 }
   1216             } break;
   1217             case SERVICE_TIMEOUT_MSG: {
   1218                 if (mDidDexOpt) {
   1219                     mDidDexOpt = false;
   1220                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
   1221                     nmsg.obj = msg.obj;
   1222                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
   1223                     return;
   1224                 }
   1225                 mServices.serviceTimeout((ProcessRecord)msg.obj);
   1226             } break;
   1227             case UPDATE_TIME_ZONE: {
   1228                 synchronized (ActivityManagerService.this) {
   1229                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1230                         ProcessRecord r = mLruProcesses.get(i);
   1231                         if (r.thread != null) {
   1232                             try {
   1233                                 r.thread.updateTimeZone();
   1234                             } catch (RemoteException ex) {
   1235                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
   1236                             }
   1237                         }
   1238                     }
   1239                 }
   1240             } break;
   1241             case CLEAR_DNS_CACHE_MSG: {
   1242                 synchronized (ActivityManagerService.this) {
   1243                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1244                         ProcessRecord r = mLruProcesses.get(i);
   1245                         if (r.thread != null) {
   1246                             try {
   1247                                 r.thread.clearDnsCache();
   1248                             } catch (RemoteException ex) {
   1249                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
   1250                             }
   1251                         }
   1252                     }
   1253                 }
   1254             } break;
   1255             case UPDATE_HTTP_PROXY_MSG: {
   1256                 ProxyProperties proxy = (ProxyProperties)msg.obj;
   1257                 String host = "";
   1258                 String port = "";
   1259                 String exclList = "";
   1260                 String pacFileUrl = null;
   1261                 if (proxy != null) {
   1262                     host = proxy.getHost();
   1263                     port = Integer.toString(proxy.getPort());
   1264                     exclList = proxy.getExclusionList();
   1265                     pacFileUrl = proxy.getPacFileUrl();
   1266                 }
   1267                 synchronized (ActivityManagerService.this) {
   1268                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   1269                         ProcessRecord r = mLruProcesses.get(i);
   1270                         if (r.thread != null) {
   1271                             try {
   1272                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
   1273                             } catch (RemoteException ex) {
   1274                                 Slog.w(TAG, "Failed to update http proxy for: " +
   1275                                         r.info.processName);
   1276                             }
   1277                         }
   1278                     }
   1279                 }
   1280             } break;
   1281             case SHOW_UID_ERROR_MSG: {
   1282                 String title = "System UIDs Inconsistent";
   1283                 String text = "UIDs on the system are inconsistent, you need to wipe your"
   1284                         + " data partition or your device will be unstable.";
   1285                 Log.e(TAG, title + ": " + text);
   1286                 if (mShowDialogs) {
   1287                     // XXX This is a temporary dialog, no need to localize.
   1288                     AlertDialog d = new BaseErrorDialog(mContext);
   1289                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
   1290                     d.setCancelable(false);
   1291                     d.setTitle(title);
   1292                     d.setMessage(text);
   1293                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
   1294                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
   1295                     mUidAlert = d;
   1296                     d.show();
   1297                 }
   1298             } break;
   1299             case IM_FEELING_LUCKY_MSG: {
   1300                 if (mUidAlert != null) {
   1301                     mUidAlert.dismiss();
   1302                     mUidAlert = null;
   1303                 }
   1304             } break;
   1305             case PROC_START_TIMEOUT_MSG: {
   1306                 if (mDidDexOpt) {
   1307                     mDidDexOpt = false;
   1308                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   1309                     nmsg.obj = msg.obj;
   1310                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
   1311                     return;
   1312                 }
   1313                 ProcessRecord app = (ProcessRecord)msg.obj;
   1314                 synchronized (ActivityManagerService.this) {
   1315                     processStartTimedOutLocked(app);
   1316                 }
   1317             } break;
   1318             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
   1319                 synchronized (ActivityManagerService.this) {
   1320                     doPendingActivityLaunchesLocked(true);
   1321                 }
   1322             } break;
   1323             case KILL_APPLICATION_MSG: {
   1324                 synchronized (ActivityManagerService.this) {
   1325                     int appid = msg.arg1;
   1326                     boolean restart = (msg.arg2 == 1);
   1327                     Bundle bundle = (Bundle)msg.obj;
   1328                     String pkg = bundle.getString("pkg");
   1329                     String reason = bundle.getString("reason");
   1330                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
   1331                             false, UserHandle.USER_ALL, reason);
   1332                 }
   1333             } break;
   1334             case FINALIZE_PENDING_INTENT_MSG: {
   1335                 ((PendingIntentRecord)msg.obj).completeFinalize();
   1336             } break;
   1337             case POST_HEAVY_NOTIFICATION_MSG: {
   1338                 INotificationManager inm = NotificationManager.getService();
   1339                 if (inm == null) {
   1340                     return;
   1341                 }
   1342 
   1343                 ActivityRecord root = (ActivityRecord)msg.obj;
   1344                 ProcessRecord process = root.app;
   1345                 if (process == null) {
   1346                     return;
   1347                 }
   1348 
   1349                 try {
   1350                     Context context = mContext.createPackageContext(process.info.packageName, 0);
   1351                     String text = mContext.getString(R.string.heavy_weight_notification,
   1352                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
   1353                     Notification notification = new Notification();
   1354                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
   1355                     notification.when = 0;
   1356                     notification.flags = Notification.FLAG_ONGOING_EVENT;
   1357                     notification.tickerText = text;
   1358                     notification.defaults = 0; // please be quiet
   1359                     notification.sound = null;
   1360                     notification.vibrate = null;
   1361                     notification.setLatestEventInfo(context, text,
   1362                             mContext.getText(R.string.heavy_weight_notification_detail),
   1363                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
   1364                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
   1365                                     new UserHandle(root.userId)));
   1366 
   1367                     try {
   1368                         int[] outId = new int[1];
   1369                         inm.enqueueNotificationWithTag("android", "android", null,
   1370                                 R.string.heavy_weight_notification,
   1371                                 notification, outId, root.userId);
   1372                     } catch (RuntimeException e) {
   1373                         Slog.w(ActivityManagerService.TAG,
   1374                                 "Error showing notification for heavy-weight app", e);
   1375                     } catch (RemoteException e) {
   1376                     }
   1377                 } catch (NameNotFoundException e) {
   1378                     Slog.w(TAG, "Unable to create context for heavy notification", e);
   1379                 }
   1380             } break;
   1381             case CANCEL_HEAVY_NOTIFICATION_MSG: {
   1382                 INotificationManager inm = NotificationManager.getService();
   1383                 if (inm == null) {
   1384                     return;
   1385                 }
   1386                 try {
   1387                     inm.cancelNotificationWithTag("android", null,
   1388                             R.string.heavy_weight_notification,  msg.arg1);
   1389                 } catch (RuntimeException e) {
   1390                     Slog.w(ActivityManagerService.TAG,
   1391                             "Error canceling notification for service", e);
   1392                 } catch (RemoteException e) {
   1393                 }
   1394             } break;
   1395             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
   1396                 synchronized (ActivityManagerService.this) {
   1397                     checkExcessivePowerUsageLocked(true);
   1398                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1399                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   1400                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   1401                 }
   1402             } break;
   1403             case SHOW_COMPAT_MODE_DIALOG_MSG: {
   1404                 synchronized (ActivityManagerService.this) {
   1405                     ActivityRecord ar = (ActivityRecord)msg.obj;
   1406                     if (mCompatModeDialog != null) {
   1407                         if (mCompatModeDialog.mAppInfo.packageName.equals(
   1408                                 ar.info.applicationInfo.packageName)) {
   1409                             return;
   1410                         }
   1411                         mCompatModeDialog.dismiss();
   1412                         mCompatModeDialog = null;
   1413                     }
   1414                     if (ar != null && false) {
   1415                         if (mCompatModePackages.getPackageAskCompatModeLocked(
   1416                                 ar.packageName)) {
   1417                             int mode = mCompatModePackages.computeCompatModeLocked(
   1418                                     ar.info.applicationInfo);
   1419                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
   1420                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
   1421                                 mCompatModeDialog = new CompatModeDialog(
   1422                                         ActivityManagerService.this, mContext,
   1423                                         ar.info.applicationInfo);
   1424                                 mCompatModeDialog.show();
   1425                             }
   1426                         }
   1427                     }
   1428                 }
   1429                 break;
   1430             }
   1431             case DISPATCH_PROCESSES_CHANGED: {
   1432                 dispatchProcessesChanged();
   1433                 break;
   1434             }
   1435             case DISPATCH_PROCESS_DIED: {
   1436                 final int pid = msg.arg1;
   1437                 final int uid = msg.arg2;
   1438                 dispatchProcessDied(pid, uid);
   1439                 break;
   1440             }
   1441             case REPORT_MEM_USAGE_MSG: {
   1442                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
   1443                 Thread thread = new Thread() {
   1444                     @Override public void run() {
   1445                         final SparseArray<ProcessMemInfo> infoMap
   1446                                 = new SparseArray<ProcessMemInfo>(memInfos.size());
   1447                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1448                             ProcessMemInfo mi = memInfos.get(i);
   1449                             infoMap.put(mi.pid, mi);
   1450                         }
   1451                         updateCpuStatsNow();
   1452                         synchronized (mProcessCpuThread) {
   1453                             final int N = mProcessCpuTracker.countStats();
   1454                             for (int i=0; i<N; i++) {
   1455                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   1456                                 if (st.vsize > 0) {
   1457                                     long pss = Debug.getPss(st.pid, null);
   1458                                     if (pss > 0) {
   1459                                         if (infoMap.indexOfKey(st.pid) < 0) {
   1460                                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
   1461                                                     ProcessList.NATIVE_ADJ, -1, "native", null);
   1462                                             mi.pss = pss;
   1463                                             memInfos.add(mi);
   1464                                         }
   1465                                     }
   1466                                 }
   1467                             }
   1468                         }
   1469 
   1470                         long totalPss = 0;
   1471                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1472                             ProcessMemInfo mi = memInfos.get(i);
   1473                             if (mi.pss == 0) {
   1474                                 mi.pss = Debug.getPss(mi.pid, null);
   1475                             }
   1476                             totalPss += mi.pss;
   1477                         }
   1478                         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
   1479                             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
   1480                                 if (lhs.oomAdj != rhs.oomAdj) {
   1481                                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
   1482                                 }
   1483                                 if (lhs.pss != rhs.pss) {
   1484                                     return lhs.pss < rhs.pss ? 1 : -1;
   1485                                 }
   1486                                 return 0;
   1487                             }
   1488                         });
   1489 
   1490                         StringBuilder tag = new StringBuilder(128);
   1491                         StringBuilder stack = new StringBuilder(128);
   1492                         tag.append("Low on memory -- ");
   1493                         appendMemBucket(tag, totalPss, "total", false);
   1494                         appendMemBucket(stack, totalPss, "total", true);
   1495 
   1496                         StringBuilder logBuilder = new StringBuilder(1024);
   1497                         logBuilder.append("Low on memory:\n");
   1498 
   1499                         boolean firstLine = true;
   1500                         int lastOomAdj = Integer.MIN_VALUE;
   1501                         for (int i=0, N=memInfos.size(); i<N; i++) {
   1502                             ProcessMemInfo mi = memInfos.get(i);
   1503 
   1504                             if (mi.oomAdj != ProcessList.NATIVE_ADJ
   1505                                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
   1506                                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
   1507                                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
   1508                                 if (lastOomAdj != mi.oomAdj) {
   1509                                     lastOomAdj = mi.oomAdj;
   1510                                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1511                                         tag.append(" / ");
   1512                                     }
   1513                                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
   1514                                         if (firstLine) {
   1515                                             stack.append(":");
   1516                                             firstLine = false;
   1517                                         }
   1518                                         stack.append("\n\t at ");
   1519                                     } else {
   1520                                         stack.append("$");
   1521                                     }
   1522                                 } else {
   1523                                     tag.append(" ");
   1524                                     stack.append("$");
   1525                                 }
   1526                                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   1527                                     appendMemBucket(tag, mi.pss, mi.name, false);
   1528                                 }
   1529                                 appendMemBucket(stack, mi.pss, mi.name, true);
   1530                                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
   1531                                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
   1532                                     stack.append("(");
   1533                                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
   1534                                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
   1535                                             stack.append(DUMP_MEM_OOM_LABEL[k]);
   1536                                             stack.append(":");
   1537                                             stack.append(DUMP_MEM_OOM_ADJ[k]);
   1538                                         }
   1539                                     }
   1540                                     stack.append(")");
   1541                                 }
   1542                             }
   1543 
   1544                             logBuilder.append("  ");
   1545                             logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
   1546                             logBuilder.append(' ');
   1547                             logBuilder.append(ProcessList.makeProcStateString(mi.procState));
   1548                             logBuilder.append(' ');
   1549                             ProcessList.appendRamKb(logBuilder, mi.pss);
   1550                             logBuilder.append(" kB: ");
   1551                             logBuilder.append(mi.name);
   1552                             logBuilder.append(" (");
   1553                             logBuilder.append(mi.pid);
   1554                             logBuilder.append(") ");
   1555                             logBuilder.append(mi.adjType);
   1556                             logBuilder.append('\n');
   1557                             if (mi.adjReason != null) {
   1558                                 logBuilder.append("                      ");
   1559                                 logBuilder.append(mi.adjReason);
   1560                                 logBuilder.append('\n');
   1561                             }
   1562                         }
   1563 
   1564                         logBuilder.append("           ");
   1565                         ProcessList.appendRamKb(logBuilder, totalPss);
   1566                         logBuilder.append(" kB: TOTAL\n");
   1567 
   1568                         long[] infos = new long[Debug.MEMINFO_COUNT];
   1569                         Debug.getMemInfo(infos);
   1570                         logBuilder.append("  MemInfo: ");
   1571                         logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
   1572                         logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
   1573                         logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
   1574                         logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
   1575                         logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
   1576                         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
   1577                             logBuilder.append("  ZRAM: ");
   1578                             logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
   1579                             logBuilder.append(" kB RAM, ");
   1580                             logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
   1581                             logBuilder.append(" kB swap total, ");
   1582                             logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
   1583                             logBuilder.append(" kB swap free\n");
   1584                         }
   1585                         Slog.i(TAG, logBuilder.toString());
   1586 
   1587                         StringBuilder dropBuilder = new StringBuilder(1024);
   1588                         /*
   1589                         StringWriter oomSw = new StringWriter();
   1590                         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
   1591                         StringWriter catSw = new StringWriter();
   1592                         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1593                         String[] emptyArgs = new String[] { };
   1594                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
   1595                         oomPw.flush();
   1596                         String oomString = oomSw.toString();
   1597                         */
   1598                         dropBuilder.append(stack);
   1599                         dropBuilder.append('\n');
   1600                         dropBuilder.append('\n');
   1601                         dropBuilder.append(logBuilder);
   1602                         dropBuilder.append('\n');
   1603                         /*
   1604                         dropBuilder.append(oomString);
   1605                         dropBuilder.append('\n');
   1606                         */
   1607                         StringWriter catSw = new StringWriter();
   1608                         synchronized (ActivityManagerService.this) {
   1609                             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
   1610                             String[] emptyArgs = new String[] { };
   1611                             catPw.println();
   1612                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
   1613                             catPw.println();
   1614                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
   1615                                     false, false, null);
   1616                             catPw.println();
   1617                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
   1618                             catPw.flush();
   1619                         }
   1620                         dropBuilder.append(catSw.toString());
   1621                         addErrorToDropBox("lowmem", null, "system_server", null,
   1622                                 null, tag.toString(), dropBuilder.toString(), null, null);
   1623                         //Slog.i(TAG, "Sent to dropbox:");
   1624                         //Slog.i(TAG, dropBuilder.toString());
   1625                         synchronized (ActivityManagerService.this) {
   1626                             long now = SystemClock.uptimeMillis();
   1627                             if (mLastMemUsageReportTime < now) {
   1628                                 mLastMemUsageReportTime = now;
   1629                             }
   1630                         }
   1631                     }
   1632                 };
   1633                 thread.start();
   1634                 break;
   1635             }
   1636             case REPORT_USER_SWITCH_MSG: {
   1637                 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1638                 break;
   1639             }
   1640             case CONTINUE_USER_SWITCH_MSG: {
   1641                 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1642                 break;
   1643             }
   1644             case USER_SWITCH_TIMEOUT_MSG: {
   1645                 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
   1646                 break;
   1647             }
   1648             case IMMERSIVE_MODE_LOCK_MSG: {
   1649                 final boolean nextState = (msg.arg1 != 0);
   1650                 if (mUpdateLock.isHeld() != nextState) {
   1651                     if (DEBUG_IMMERSIVE) {
   1652                         final ActivityRecord r = (ActivityRecord) msg.obj;
   1653                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
   1654                     }
   1655                     if (nextState) {
   1656                         mUpdateLock.acquire();
   1657                     } else {
   1658                         mUpdateLock.release();
   1659                     }
   1660                 }
   1661                 break;
   1662             }
   1663             case PERSIST_URI_GRANTS_MSG: {
   1664                 writeGrantedUriPermissions();
   1665                 break;
   1666             }
   1667             case REQUEST_ALL_PSS_MSG: {
   1668                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
   1669                 break;
   1670             }
   1671             }
   1672         }
   1673     };
   1674 
   1675     static final int COLLECT_PSS_BG_MSG = 1;
   1676 
   1677     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
   1678         @Override
   1679         public void handleMessage(Message msg) {
   1680             switch (msg.what) {
   1681             case COLLECT_PSS_BG_MSG: {
   1682                 int i=0, num=0;
   1683                 long start = SystemClock.uptimeMillis();
   1684                 long[] tmp = new long[1];
   1685                 do {
   1686                     ProcessRecord proc;
   1687                     int procState;
   1688                     int pid;
   1689                     synchronized (ActivityManagerService.this) {
   1690                         if (i >= mPendingPssProcesses.size()) {
   1691                             if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
   1692                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
   1693                             mPendingPssProcesses.clear();
   1694                             return;
   1695                         }
   1696                         proc = mPendingPssProcesses.get(i);
   1697                         procState = proc.pssProcState;
   1698                         if (proc.thread != null && procState == proc.setProcState) {
   1699                             pid = proc.pid;
   1700                         } else {
   1701                             proc = null;
   1702                             pid = 0;
   1703                         }
   1704                         i++;
   1705                     }
   1706                     if (proc != null) {
   1707                         long pss = Debug.getPss(pid, tmp);
   1708                         synchronized (ActivityManagerService.this) {
   1709                             if (proc.thread != null && proc.setProcState == procState
   1710                                     && proc.pid == pid) {
   1711                                 num++;
   1712                                 proc.lastPssTime = SystemClock.uptimeMillis();
   1713                                 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
   1714                                 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
   1715                                         + ": " + pss + " lastPss=" + proc.lastPss
   1716                                         + " state=" + ProcessList.makeProcStateString(procState));
   1717                                 if (proc.initialIdlePss == 0) {
   1718                                     proc.initialIdlePss = pss;
   1719                                 }
   1720                                 proc.lastPss = pss;
   1721                                 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
   1722                                     proc.lastCachedPss = pss;
   1723                                 }
   1724                             }
   1725                         }
   1726                     }
   1727                 } while (true);
   1728             }
   1729             }
   1730         }
   1731     };
   1732 
   1733     public static void setSystemProcess() {
   1734         try {
   1735             ActivityManagerService m = mSelf;
   1736 
   1737             ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
   1738             ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
   1739             ServiceManager.addService("meminfo", new MemBinder(m));
   1740             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
   1741             ServiceManager.addService("dbinfo", new DbBinder(m));
   1742             if (MONITOR_CPU_USAGE) {
   1743                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
   1744             }
   1745             ServiceManager.addService("permission", new PermissionController(m));
   1746 
   1747             ApplicationInfo info =
   1748                 mSelf.mContext.getPackageManager().getApplicationInfo(
   1749                             "android", STOCK_PM_FLAGS);
   1750             mSystemThread.installSystemApplicationInfo(info);
   1751 
   1752             synchronized (mSelf) {
   1753                 ProcessRecord app = mSelf.newProcessRecordLocked(info,
   1754                         info.processName, false);
   1755                 app.persistent = true;
   1756                 app.pid = MY_PID;
   1757                 app.maxAdj = ProcessList.SYSTEM_ADJ;
   1758                 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
   1759                 mSelf.mProcessNames.put(app.processName, app.uid, app);
   1760                 synchronized (mSelf.mPidsSelfLocked) {
   1761                     mSelf.mPidsSelfLocked.put(app.pid, app);
   1762                 }
   1763                 mSelf.updateLruProcessLocked(app, false, null);
   1764                 mSelf.updateOomAdjLocked();
   1765             }
   1766         } catch (PackageManager.NameNotFoundException e) {
   1767             throw new RuntimeException(
   1768                     "Unable to find android system package", e);
   1769         }
   1770     }
   1771 
   1772     public void setWindowManager(WindowManagerService wm) {
   1773         mWindowManager = wm;
   1774         mStackSupervisor.setWindowManager(wm);
   1775         wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
   1776     }
   1777 
   1778     public void startObservingNativeCrashes() {
   1779         final NativeCrashListener ncl = new NativeCrashListener();
   1780         ncl.start();
   1781     }
   1782 
   1783     public static final Context main(int factoryTest) {
   1784         AThread thr = new AThread();
   1785         thr.start();
   1786 
   1787         synchronized (thr) {
   1788             while (thr.mService == null) {
   1789                 try {
   1790                     thr.wait();
   1791                 } catch (InterruptedException e) {
   1792                 }
   1793             }
   1794         }
   1795 
   1796         ActivityManagerService m = thr.mService;
   1797         mSelf = m;
   1798         ActivityThread at = ActivityThread.systemMain();
   1799         mSystemThread = at;
   1800         Context context = at.getSystemContext();
   1801         context.setTheme(android.R.style.Theme_Holo);
   1802         m.mContext = context;
   1803         m.mFactoryTest = factoryTest;
   1804         m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
   1805 
   1806         m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
   1807 
   1808         m.mBatteryStatsService.publish(context);
   1809         m.mUsageStatsService.publish(context);
   1810         m.mAppOpsService.publish(context);
   1811 
   1812         synchronized (thr) {
   1813             thr.mReady = true;
   1814             thr.notifyAll();
   1815         }
   1816 
   1817         m.startRunning(null, null, null, null);
   1818 
   1819         return context;
   1820     }
   1821 
   1822     public static ActivityManagerService self() {
   1823         return mSelf;
   1824     }
   1825 
   1826     public IAppOpsService getAppOpsService() {
   1827         return mAppOpsService;
   1828     }
   1829 
   1830     static class AThread extends Thread {
   1831         ActivityManagerService mService;
   1832         Looper mLooper;
   1833         boolean mReady = false;
   1834 
   1835         public AThread() {
   1836             super("ActivityManager");
   1837         }
   1838 
   1839         @Override
   1840         public void run() {
   1841             Looper.prepare();
   1842 
   1843             android.os.Process.setThreadPriority(
   1844                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
   1845             android.os.Process.setCanSelfBackground(false);
   1846 
   1847             ActivityManagerService m = new ActivityManagerService();
   1848 
   1849             synchronized (this) {
   1850                 mService = m;
   1851                 mLooper = Looper.myLooper();
   1852                 Watchdog.getInstance().addThread(new Handler(mLooper), getName());
   1853                 notifyAll();
   1854             }
   1855 
   1856             synchronized (this) {
   1857                 while (!mReady) {
   1858                     try {
   1859                         wait();
   1860                     } catch (InterruptedException e) {
   1861                     }
   1862                 }
   1863             }
   1864 
   1865             // For debug builds, log event loop stalls to dropbox for analysis.
   1866             if (StrictMode.conditionallyEnableDebugLogging()) {
   1867                 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
   1868             }
   1869 
   1870             Looper.loop();
   1871         }
   1872     }
   1873 
   1874     static class MemBinder extends Binder {
   1875         ActivityManagerService mActivityManagerService;
   1876         MemBinder(ActivityManagerService activityManagerService) {
   1877             mActivityManagerService = activityManagerService;
   1878         }
   1879 
   1880         @Override
   1881         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1882             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1883                     != PackageManager.PERMISSION_GRANTED) {
   1884                 pw.println("Permission Denial: can't dump meminfo from from pid="
   1885                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1886                         + " without permission " + android.Manifest.permission.DUMP);
   1887                 return;
   1888             }
   1889 
   1890             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
   1891         }
   1892     }
   1893 
   1894     static class GraphicsBinder extends Binder {
   1895         ActivityManagerService mActivityManagerService;
   1896         GraphicsBinder(ActivityManagerService activityManagerService) {
   1897             mActivityManagerService = activityManagerService;
   1898         }
   1899 
   1900         @Override
   1901         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1902             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1903                     != PackageManager.PERMISSION_GRANTED) {
   1904                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
   1905                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1906                         + " without permission " + android.Manifest.permission.DUMP);
   1907                 return;
   1908             }
   1909 
   1910             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
   1911         }
   1912     }
   1913 
   1914     static class DbBinder extends Binder {
   1915         ActivityManagerService mActivityManagerService;
   1916         DbBinder(ActivityManagerService activityManagerService) {
   1917             mActivityManagerService = activityManagerService;
   1918         }
   1919 
   1920         @Override
   1921         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1922             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1923                     != PackageManager.PERMISSION_GRANTED) {
   1924                 pw.println("Permission Denial: can't dump dbinfo from from pid="
   1925                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1926                         + " without permission " + android.Manifest.permission.DUMP);
   1927                 return;
   1928             }
   1929 
   1930             mActivityManagerService.dumpDbInfo(fd, pw, args);
   1931         }
   1932     }
   1933 
   1934     static class CpuBinder extends Binder {
   1935         ActivityManagerService mActivityManagerService;
   1936         CpuBinder(ActivityManagerService activityManagerService) {
   1937             mActivityManagerService = activityManagerService;
   1938         }
   1939 
   1940         @Override
   1941         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1942             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
   1943                     != PackageManager.PERMISSION_GRANTED) {
   1944                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
   1945                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
   1946                         + " without permission " + android.Manifest.permission.DUMP);
   1947                 return;
   1948             }
   1949 
   1950             synchronized (mActivityManagerService.mProcessCpuThread) {
   1951                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
   1952                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
   1953                         SystemClock.uptimeMillis()));
   1954             }
   1955         }
   1956     }
   1957 
   1958     private ActivityManagerService() {
   1959         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
   1960 
   1961         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);
   1962         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);
   1963         mBroadcastQueues[0] = mFgBroadcastQueue;
   1964         mBroadcastQueues[1] = mBgBroadcastQueue;
   1965 
   1966         mServices = new ActiveServices(this);
   1967         mProviderMap = new ProviderMap(this);
   1968 
   1969         File dataDir = Environment.getDataDirectory();
   1970         File systemDir = new File(dataDir, "system");
   1971         systemDir.mkdirs();
   1972         mBatteryStatsService = new BatteryStatsService(new File(
   1973                 systemDir, "batterystats.bin").toString());
   1974         mBatteryStatsService.getActiveStatistics().readLocked();
   1975         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   1976         mOnBattery = DEBUG_POWER ? true
   1977                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
   1978         mBatteryStatsService.getActiveStatistics().setCallback(this);
   1979 
   1980         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
   1981 
   1982         mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
   1983         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
   1984 
   1985         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
   1986 
   1987         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
   1988 
   1989         // User 0 is the first and only user that runs at boot.
   1990         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
   1991         mUserLru.add(Integer.valueOf(0));
   1992         updateStartedUserArrayLocked();
   1993 
   1994         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
   1995             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
   1996 
   1997         mConfiguration.setToDefaults();
   1998         mConfiguration.setLocale(Locale.getDefault());
   1999 
   2000         mConfigurationSeq = mConfiguration.seq = 1;
   2001         mProcessCpuTracker.init();
   2002 
   2003         mCompatModePackages = new CompatModePackages(this, systemDir);
   2004 
   2005         // Add ourself to the Watchdog monitors.
   2006         Watchdog.getInstance().addMonitor(this);
   2007 
   2008         mProcessCpuThread = new Thread("CpuTracker") {
   2009             @Override
   2010             public void run() {
   2011                 while (true) {
   2012                     try {
   2013                         try {
   2014                             synchronized(this) {
   2015                                 final long now = SystemClock.uptimeMillis();
   2016                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
   2017                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
   2018                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
   2019                                 //        + ", write delay=" + nextWriteDelay);
   2020                                 if (nextWriteDelay < nextCpuDelay) {
   2021                                     nextCpuDelay = nextWriteDelay;
   2022                                 }
   2023                                 if (nextCpuDelay > 0) {
   2024                                     mProcessCpuMutexFree.set(true);
   2025                                     this.wait(nextCpuDelay);
   2026                                 }
   2027                             }
   2028                         } catch (InterruptedException e) {
   2029                         }
   2030                         updateCpuStatsNow();
   2031                     } catch (Exception e) {
   2032                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
   2033                     }
   2034                 }
   2035             }
   2036         };
   2037         mProcessCpuThread.start();
   2038     }
   2039 
   2040     @Override
   2041     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   2042             throws RemoteException {
   2043         if (code == SYSPROPS_TRANSACTION) {
   2044             // We need to tell all apps about the system property change.
   2045             ArrayList<IBinder> procs = new ArrayList<IBinder>();
   2046             synchronized(this) {
   2047                 final int NP = mProcessNames.getMap().size();
   2048                 for (int ip=0; ip<NP; ip++) {
   2049                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   2050                     final int NA = apps.size();
   2051                     for (int ia=0; ia<NA; ia++) {
   2052                         ProcessRecord app = apps.valueAt(ia);
   2053                         if (app.thread != null) {
   2054                             procs.add(app.thread.asBinder());
   2055                         }
   2056                     }
   2057                 }
   2058             }
   2059 
   2060             int N = procs.size();
   2061             for (int i=0; i<N; i++) {
   2062                 Parcel data2 = Parcel.obtain();
   2063                 try {
   2064                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
   2065                 } catch (RemoteException e) {
   2066                 }
   2067                 data2.recycle();
   2068             }
   2069         }
   2070         try {
   2071             return super.onTransact(code, data, reply, flags);
   2072         } catch (RuntimeException e) {
   2073             // The activity manager only throws security exceptions, so let's
   2074             // log all others.
   2075             if (!(e instanceof SecurityException)) {
   2076                 Slog.wtf(TAG, "Activity Manager Crash", e);
   2077             }
   2078             throw e;
   2079         }
   2080     }
   2081 
   2082     void updateCpuStats() {
   2083         final long now = SystemClock.uptimeMillis();
   2084         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
   2085             return;
   2086         }
   2087         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
   2088             synchronized (mProcessCpuThread) {
   2089                 mProcessCpuThread.notify();
   2090             }
   2091         }
   2092     }
   2093 
   2094     void updateCpuStatsNow() {
   2095         synchronized (mProcessCpuThread) {
   2096             mProcessCpuMutexFree.set(false);
   2097             final long now = SystemClock.uptimeMillis();
   2098             boolean haveNewCpuStats = false;
   2099 
   2100             if (MONITOR_CPU_USAGE &&
   2101                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
   2102                 mLastCpuTime.set(now);
   2103                 haveNewCpuStats = true;
   2104                 mProcessCpuTracker.update();
   2105                 //Slog.i(TAG, mProcessCpu.printCurrentState());
   2106                 //Slog.i(TAG, "Total CPU usage: "
   2107                 //        + mProcessCpu.getTotalCpuPercent() + "%");
   2108 
   2109                 // Slog the cpu usage if the property is set.
   2110                 if ("true".equals(SystemProperties.get("events.cpu"))) {
   2111                     int user = mProcessCpuTracker.getLastUserTime();
   2112                     int system = mProcessCpuTracker.getLastSystemTime();
   2113                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
   2114                     int irq = mProcessCpuTracker.getLastIrqTime();
   2115                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
   2116                     int idle = mProcessCpuTracker.getLastIdleTime();
   2117 
   2118                     int total = user + system + iowait + irq + softIrq + idle;
   2119                     if (total == 0) total = 1;
   2120 
   2121                     EventLog.writeEvent(EventLogTags.CPU,
   2122                             ((user+system+iowait+irq+softIrq) * 100) / total,
   2123                             (user * 100) / total,
   2124                             (system * 100) / total,
   2125                             (iowait * 100) / total,
   2126                             (irq * 100) / total,
   2127                             (softIrq * 100) / total);
   2128                 }
   2129             }
   2130 
   2131             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
   2132             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
   2133             synchronized(bstats) {
   2134                 synchronized(mPidsSelfLocked) {
   2135                     if (haveNewCpuStats) {
   2136                         if (mOnBattery) {
   2137                             int perc = bstats.startAddingCpuLocked();
   2138                             int totalUTime = 0;
   2139                             int totalSTime = 0;
   2140                             final int N = mProcessCpuTracker.countStats();
   2141                             for (int i=0; i<N; i++) {
   2142                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   2143                                 if (!st.working) {
   2144                                     continue;
   2145                                 }
   2146                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
   2147                                 int otherUTime = (st.rel_utime*perc)/100;
   2148                                 int otherSTime = (st.rel_stime*perc)/100;
   2149                                 totalUTime += otherUTime;
   2150                                 totalSTime += otherSTime;
   2151                                 if (pr != null) {
   2152                                     BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
   2153                                             st.name, st.pid);
   2154                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2155                                             st.rel_stime-otherSTime);
   2156                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2157                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
   2158                                 } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
   2159                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
   2160                                     if (ps == null) {
   2161                                         st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
   2162                                                 "(Unknown)");
   2163                                     }
   2164                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2165                                             st.rel_stime-otherSTime);
   2166                                     ps.addSpeedStepTimes(cpuSpeedTimes);
   2167                                 } else {
   2168                                     BatteryStatsImpl.Uid.Proc ps =
   2169                                             bstats.getProcessStatsLocked(st.name, st.pid);
   2170                                     if (ps != null) {
   2171                                         ps.addCpuTimeLocked(st.rel_utime-otherUTime,
   2172                                                 st.rel_stime-otherSTime);
   2173                                         ps.addSpeedStepTimes(cpuSpeedTimes);
   2174                                     }
   2175                                 }
   2176                             }
   2177                             bstats.finishAddingCpuLocked(perc, totalUTime,
   2178                                     totalSTime, cpuSpeedTimes);
   2179                         }
   2180                     }
   2181                 }
   2182 
   2183                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
   2184                     mLastWriteTime = now;
   2185                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
   2186                 }
   2187             }
   2188         }
   2189     }
   2190 
   2191     @Override
   2192     public void batteryNeedsCpuUpdate() {
   2193         updateCpuStatsNow();
   2194     }
   2195 
   2196     @Override
   2197     public void batteryPowerChanged(boolean onBattery) {
   2198         // When plugging in, update the CPU stats first before changing
   2199         // the plug state.
   2200         updateCpuStatsNow();
   2201         synchronized (this) {
   2202             synchronized(mPidsSelfLocked) {
   2203                 mOnBattery = DEBUG_POWER ? true : onBattery;
   2204             }
   2205         }
   2206     }
   2207 
   2208     /**
   2209      * Initialize the application bind args. These are passed to each
   2210      * process when the bindApplication() IPC is sent to the process. They're
   2211      * lazily setup to make sure the services are running when they're asked for.
   2212      */
   2213     private HashMap<String, IBinder> getCommonServicesLocked() {
   2214         if (mAppBindArgs == null) {
   2215             mAppBindArgs = new HashMap<String, IBinder>();
   2216 
   2217             // Setup the application init args
   2218             mAppBindArgs.put("package", ServiceManager.getService("package"));
   2219             mAppBindArgs.put("window", ServiceManager.getService("window"));
   2220             mAppBindArgs.put(Context.ALARM_SERVICE,
   2221                     ServiceManager.getService(Context.ALARM_SERVICE));
   2222         }
   2223         return mAppBindArgs;
   2224     }
   2225 
   2226     final void setFocusedActivityLocked(ActivityRecord r) {
   2227         if (mFocusedActivity != r) {
   2228             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
   2229             mFocusedActivity = r;
   2230             mStackSupervisor.setFocusedStack(r);
   2231             if (r != null) {
   2232                 mWindowManager.setFocusedApp(r.appToken, true);
   2233             }
   2234             applyUpdateLockStateLocked(r);
   2235         }
   2236     }
   2237 
   2238     @Override
   2239     public void setFocusedStack(int stackId) {
   2240         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
   2241         synchronized (ActivityManagerService.this) {
   2242             ActivityStack stack = mStackSupervisor.getStack(stackId);
   2243             if (stack != null) {
   2244                 ActivityRecord r = stack.topRunningActivityLocked(null);
   2245                 if (r != null) {
   2246                     setFocusedActivityLocked(r);
   2247                 }
   2248             }
   2249         }
   2250     }
   2251 
   2252     @Override
   2253     public void notifyActivityDrawn(IBinder token) {
   2254         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
   2255         synchronized (this) {
   2256             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
   2257             if (r != null) {
   2258                 r.task.stack.notifyActivityDrawnLocked(r);
   2259             }
   2260         }
   2261     }
   2262 
   2263     final void applyUpdateLockStateLocked(ActivityRecord r) {
   2264         // Modifications to the UpdateLock state are done on our handler, outside
   2265         // the activity manager's locks.  The new state is determined based on the
   2266         // state *now* of the relevant activity record.  The object is passed to
   2267         // the handler solely for logging detail, not to be consulted/modified.
   2268         final boolean nextState = r != null && r.immersive;
   2269         mHandler.sendMessage(
   2270                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
   2271     }
   2272 
   2273     final void showAskCompatModeDialogLocked(ActivityRecord r) {
   2274         Message msg = Message.obtain();
   2275         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
   2276         msg.obj = r.task.askedCompatMode ? null : r;
   2277         mHandler.sendMessage(msg);
   2278     }
   2279 
   2280     private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
   2281             String what, Object obj, ProcessRecord srcApp) {
   2282         app.lastActivityTime = now;
   2283 
   2284         if (app.activities.size() > 0) {
   2285             // Don't want to touch dependent processes that are hosting activities.
   2286             return index;
   2287         }
   2288 
   2289         int lrui = mLruProcesses.lastIndexOf(app);
   2290         if (lrui < 0) {
   2291             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
   2292                     + what + " " + obj + " from " + srcApp);
   2293             return index;
   2294         }
   2295 
   2296         if (lrui >= index) {
   2297             // Don't want to cause this to move dependent processes *back* in the
   2298             // list as if they were less frequently used.
   2299             return index;
   2300         }
   2301 
   2302         if (lrui >= mLruProcessActivityStart) {
   2303             // Don't want to touch dependent processes that are hosting activities.
   2304             return index;
   2305         }
   2306 
   2307         mLruProcesses.remove(lrui);
   2308         if (index > 0) {
   2309             index--;
   2310         }
   2311         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
   2312                 + " in LRU list: " + app);
   2313         mLruProcesses.add(index, app);
   2314         return index;
   2315     }
   2316 
   2317     final void removeLruProcessLocked(ProcessRecord app) {
   2318         int lrui = mLruProcesses.lastIndexOf(app);
   2319         if (lrui >= 0) {
   2320             if (lrui <= mLruProcessActivityStart) {
   2321                 mLruProcessActivityStart--;
   2322             }
   2323             if (lrui <= mLruProcessServiceStart) {
   2324                 mLruProcessServiceStart--;
   2325             }
   2326             mLruProcesses.remove(lrui);
   2327         }
   2328     }
   2329 
   2330     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
   2331             ProcessRecord client) {
   2332         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
   2333         final boolean hasService = false; // not impl yet. app.services.size() > 0;
   2334         if (!activityChange && hasActivity) {
   2335             // The process has activties, so we are only going to allow activity-based
   2336             // adjustments move it.  It should be kept in the front of the list with other
   2337             // processes that have activities, and we don't want those to change their
   2338             // order except due to activity operations.
   2339             return;
   2340         }
   2341 
   2342         mLruSeq++;
   2343         final long now = SystemClock.uptimeMillis();
   2344         app.lastActivityTime = now;
   2345 
   2346         // First a quick reject: if the app is already at the position we will
   2347         // put it, then there is nothing to do.
   2348         if (hasActivity) {
   2349             final int N = mLruProcesses.size();
   2350             if (N > 0 && mLruProcesses.get(N-1) == app) {
   2351                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
   2352                 return;
   2353             }
   2354         } else {
   2355             if (mLruProcessServiceStart > 0
   2356                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
   2357                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
   2358                 return;
   2359             }
   2360         }
   2361 
   2362         int lrui = mLruProcesses.lastIndexOf(app);
   2363 
   2364         if (app.persistent && lrui >= 0) {
   2365             // We don't care about the position of persistent processes, as long as
   2366             // they are in the list.
   2367             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
   2368             return;
   2369         }
   2370 
   2371         /* In progress: compute new position first, so we can avoid doing work
   2372            if the process is not actually going to move.  Not yet working.
   2373         int addIndex;
   2374         int nextIndex;
   2375         boolean inActivity = false, inService = false;
   2376         if (hasActivity) {
   2377             // Process has activities, put it at the very tipsy-top.
   2378             addIndex = mLruProcesses.size();
   2379             nextIndex = mLruProcessServiceStart;
   2380             inActivity = true;
   2381         } else if (hasService) {
   2382             // Process has services, put it at the top of the service list.
   2383             addIndex = mLruProcessActivityStart;
   2384             nextIndex = mLruProcessServiceStart;
   2385             inActivity = true;
   2386             inService = true;
   2387         } else  {
   2388             // Process not otherwise of interest, it goes to the top of the non-service area.
   2389             addIndex = mLruProcessServiceStart;
   2390             if (client != null) {
   2391                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2392                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
   2393                         + app);
   2394                 if (clientIndex >= 0 && addIndex > clientIndex) {
   2395                     addIndex = clientIndex;
   2396                 }
   2397             }
   2398             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
   2399         }
   2400 
   2401         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
   2402                 + mLruProcessActivityStart + "): " + app);
   2403         */
   2404 
   2405         if (lrui >= 0) {
   2406             if (lrui < mLruProcessActivityStart) {
   2407                 mLruProcessActivityStart--;
   2408             }
   2409             if (lrui < mLruProcessServiceStart) {
   2410                 mLruProcessServiceStart--;
   2411             }
   2412             /*
   2413             if (addIndex > lrui) {
   2414                 addIndex--;
   2415             }
   2416             if (nextIndex > lrui) {
   2417                 nextIndex--;
   2418             }
   2419             */
   2420             mLruProcesses.remove(lrui);
   2421         }
   2422 
   2423         /*
   2424         mLruProcesses.add(addIndex, app);
   2425         if (inActivity) {
   2426             mLruProcessActivityStart++;
   2427         }
   2428         if (inService) {
   2429             mLruProcessActivityStart++;
   2430         }
   2431         */
   2432 
   2433         int nextIndex;
   2434         if (hasActivity) {
   2435             final int N = mLruProcesses.size();
   2436             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
   2437                 // Process doesn't have activities, but has clients with
   2438                 // activities...  move it up, but one below the top (the top
   2439                 // should always have a real activity).
   2440                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
   2441                 mLruProcesses.add(N-1, app);
   2442                 // To keep it from spamming the LRU list (by making a bunch of clients),
   2443                 // we will push down any other entries owned by the app.
   2444                 final int uid = app.info.uid;
   2445                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
   2446                     ProcessRecord subProc = mLruProcesses.get(i);
   2447                     if (subProc.info.uid == uid) {
   2448                         // We want to push this one down the list.  If the process after
   2449                         // it is for the same uid, however, don't do so, because we don't
   2450                         // want them internally to be re-ordered.
   2451                         if (mLruProcesses.get(i-1).info.uid != uid) {
   2452                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
   2453                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
   2454                             ProcessRecord tmp = mLruProcesses.get(i);
   2455                             mLruProcesses.set(i, mLruProcesses.get(i-1));
   2456                             mLruProcesses.set(i-1, tmp);
   2457                             i--;
   2458                         }
   2459                     } else {
   2460                         // A gap, we can stop here.
   2461                         break;
   2462                     }
   2463                 }
   2464             } else {
   2465                 // Process has activities, put it at the very tipsy-top.
   2466                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
   2467                 mLruProcesses.add(app);
   2468             }
   2469             nextIndex = mLruProcessServiceStart;
   2470         } else if (hasService) {
   2471             // Process has services, put it at the top of the service list.
   2472             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
   2473             mLruProcesses.add(mLruProcessActivityStart, app);
   2474             nextIndex = mLruProcessServiceStart;
   2475             mLruProcessActivityStart++;
   2476         } else  {
   2477             // Process not otherwise of interest, it goes to the top of the non-service area.
   2478             int index = mLruProcessServiceStart;
   2479             if (client != null) {
   2480                 // If there is a client, don't allow the process to be moved up higher
   2481                 // in the list than that client.
   2482                 int clientIndex = mLruProcesses.lastIndexOf(client);
   2483                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
   2484                         + " when updating " + app);
   2485                 if (clientIndex <= lrui) {
   2486                     // Don't allow the client index restriction to push it down farther in the
   2487                     // list than it already is.
   2488                     clientIndex = lrui;
   2489                 }
   2490                 if (clientIndex >= 0 && index > clientIndex) {
   2491                     index = clientIndex;
   2492                 }
   2493             }
   2494             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
   2495             mLruProcesses.add(index, app);
   2496             nextIndex = index-1;
   2497             mLruProcessActivityStart++;
   2498             mLruProcessServiceStart++;
   2499         }
   2500 
   2501         // If the app is currently using a content provider or service,
   2502         // bump those processes as well.
   2503         for (int j=app.connections.size()-1; j>=0; j--) {
   2504             ConnectionRecord cr = app.connections.valueAt(j);
   2505             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
   2506                     && cr.binding.service.app != null
   2507                     && cr.binding.service.app.lruSeq != mLruSeq
   2508                     && !cr.binding.service.app.persistent) {
   2509                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
   2510                         "service connection", cr, app);
   2511             }
   2512         }
   2513         for (int j=app.conProviders.size()-1; j>=0; j--) {
   2514             ContentProviderRecord cpr = app.conProviders.get(j).provider;
   2515             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
   2516                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
   2517                         "provider reference", cpr, app);
   2518             }
   2519         }
   2520     }
   2521 
   2522     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
   2523         if (uid == Process.SYSTEM_UID) {
   2524             // The system gets to run in any process.  If there are multiple
   2525             // processes with the same uid, just pick the first (this
   2526             // should never happen).
   2527             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
   2528             if (procs == null) return null;
   2529             final int N = procs.size();
   2530             for (int i = 0; i < N; i++) {
   2531                 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
   2532             }
   2533         }
   2534         ProcessRecord proc = mProcessNames.get(processName, uid);
   2535         if (false && proc != null && !keepIfLarge
   2536                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
   2537                 && proc.lastCachedPss >= 4000) {
   2538             // Turn this condition on to cause killing to happen regularly, for testing.
   2539             if (proc.baseProcessTracker != null) {
   2540                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2541             }
   2542             killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
   2543                     + "k from cached");
   2544         } else if (proc != null && !keepIfLarge
   2545                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   2546                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
   2547             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
   2548             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
   2549                 if (proc.baseProcessTracker != null) {
   2550                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
   2551                 }
   2552                 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
   2553                         + "k from cached");
   2554             }
   2555         }
   2556         return proc;
   2557     }
   2558 
   2559     void ensurePackageDexOpt(String packageName) {
   2560         IPackageManager pm = AppGlobals.getPackageManager();
   2561         try {
   2562             if (pm.performDexOpt(packageName)) {
   2563                 mDidDexOpt = true;
   2564             }
   2565         } catch (RemoteException e) {
   2566         }
   2567     }
   2568 
   2569     boolean isNextTransitionForward() {
   2570         int transit = mWindowManager.getPendingAppTransition();
   2571         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
   2572                 || transit == AppTransition.TRANSIT_TASK_OPEN
   2573                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
   2574     }
   2575 
   2576     final ProcessRecord startProcessLocked(String processName,
   2577             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
   2578             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
   2579             boolean isolated, boolean keepIfLarge) {
   2580         ProcessRecord app;
   2581         if (!isolated) {
   2582             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
   2583         } else {
   2584             // If this is an isolated process, it can't re-use an existing process.
   2585             app = null;
   2586         }
   2587         // We don't have to do anything more if:
   2588         // (1) There is an existing application record; and
   2589         // (2) The caller doesn't think it is dead, OR there is no thread
   2590         //     object attached to it so we know it couldn't have crashed; and
   2591         // (3) There is a pid assigned to it, so it is either starting or
   2592         //     already running.
   2593         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
   2594                 + " app=" + app + " knownToBeDead=" + knownToBeDead
   2595                 + " thread=" + (app != null ? app.thread : null)
   2596                 + " pid=" + (app != null ? app.pid : -1));
   2597         if (app != null && app.pid > 0) {
   2598             if (!knownToBeDead || app.thread == null) {
   2599                 // We already have the app running, or are waiting for it to
   2600                 // come up (we have a pid but not yet its thread), so keep it.
   2601                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
   2602                 // If this is a new package in the process, add the package to the list
   2603                 app.addPackage(info.packageName, mProcessStats);
   2604                 return app;
   2605             }
   2606 
   2607             // An application record is attached to a previous process,
   2608             // clean it up now.
   2609             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
   2610             handleAppDiedLocked(app, true, true);
   2611         }
   2612 
   2613         String hostingNameStr = hostingName != null
   2614                 ? hostingName.flattenToShortString() : null;
   2615 
   2616         if (!isolated) {
   2617             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
   2618                 // If we are in the background, then check to see if this process
   2619                 // is bad.  If so, we will just silently fail.
   2620                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2621                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
   2622                             + "/" + info.processName);
   2623                     return null;
   2624                 }
   2625             } else {
   2626                 // When the user is explicitly starting a process, then clear its
   2627                 // crash count so that we won't make it bad until they see at
   2628                 // least one crash dialog again, and make the process good again
   2629                 // if it had been bad.
   2630                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
   2631                         + "/" + info.processName);
   2632                 mProcessCrashTimes.remove(info.processName, info.uid);
   2633                 if (mBadProcesses.get(info.processName, info.uid) != null) {
   2634                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
   2635                             UserHandle.getUserId(info.uid), info.uid,
   2636                             info.processName);
   2637                     mBadProcesses.remove(info.processName, info.uid);
   2638                     if (app != null) {
   2639                         app.bad = false;
   2640                     }
   2641                 }
   2642             }
   2643         }
   2644 
   2645         if (app == null) {
   2646             app = newProcessRecordLocked(info, processName, isolated);
   2647             if (app == null) {
   2648                 Slog.w(TAG, "Failed making new process record for "
   2649                         + processName + "/" + info.uid + " isolated=" + isolated);
   2650                 return null;
   2651             }
   2652             mProcessNames.put(processName, app.uid, app);
   2653             if (isolated) {
   2654                 mIsolatedProcesses.put(app.uid, app);
   2655             }
   2656         } else {
   2657             // If this is a new package in the process, add the package to the list
   2658             app.addPackage(info.packageName, mProcessStats);
   2659         }
   2660 
   2661         // If the system is not ready yet, then hold off on starting this
   2662         // process until it is.
   2663         if (!mProcessesReady
   2664                 && !isAllowedWhileBooting(info)
   2665                 && !allowWhileBooting) {
   2666             if (!mProcessesOnHold.contains(app)) {
   2667                 mProcessesOnHold.add(app);
   2668             }
   2669             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
   2670             return app;
   2671         }
   2672 
   2673         startProcessLocked(app, hostingType, hostingNameStr);
   2674         return (app.pid != 0) ? app : null;
   2675     }
   2676 
   2677     boolean isAllowedWhileBooting(ApplicationInfo ai) {
   2678         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
   2679     }
   2680 
   2681     private final void startProcessLocked(ProcessRecord app,
   2682             String hostingType, String hostingNameStr) {
   2683         if (app.pid > 0 && app.pid != MY_PID) {
   2684             synchronized (mPidsSelfLocked) {
   2685                 mPidsSelfLocked.remove(app.pid);
   2686                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   2687             }
   2688             app.setPid(0);
   2689         }
   2690 
   2691         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   2692                 "startProcessLocked removing on hold: " + app);
   2693         mProcessesOnHold.remove(app);
   2694 
   2695         updateCpuStats();
   2696 
   2697         try {
   2698             int uid = app.uid;
   2699 
   2700             int[] gids = null;
   2701             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
   2702             if (!app.isolated) {
   2703                 int[] permGids = null;
   2704                 try {
   2705                     final PackageManager pm = mContext.getPackageManager();
   2706                     permGids = pm.getPackageGids(app.info.packageName);
   2707 
   2708                     if (Environment.isExternalStorageEmulated()) {
   2709                         if (pm.checkPermission(
   2710                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
   2711                                 app.info.packageName) == PERMISSION_GRANTED) {
   2712                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
   2713                         } else {
   2714                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
   2715                         }
   2716                     }
   2717                 } catch (PackageManager.NameNotFoundException e) {
   2718                     Slog.w(TAG, "Unable to retrieve gids", e);
   2719                 }
   2720 
   2721                 /*
   2722                  * Add shared application GID so applications can share some
   2723                  * resources like shared libraries
   2724                  */
   2725                 if (permGids == null) {
   2726                     gids = new int[1];
   2727                 } else {
   2728                     gids = new int[permGids.length + 1];
   2729                     System.arraycopy(permGids, 0, gids, 1, permGids.length);
   2730                 }
   2731                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
   2732             }
   2733             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
   2734                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2735                         && mTopComponent != null
   2736                         && app.processName.equals(mTopComponent.getPackageName())) {
   2737                     uid = 0;
   2738                 }
   2739                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
   2740                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
   2741                     uid = 0;
   2742                 }
   2743             }
   2744             int debugFlags = 0;
   2745             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
   2746                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
   2747                 // Also turn on CheckJNI for debuggable apps. It's quite
   2748                 // awkward to turn on otherwise.
   2749                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2750             }
   2751             // Run the app in safe mode if its manifest requests so or the
   2752             // system is booted in safe mode.
   2753             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
   2754                 Zygote.systemInSafeMode == true) {
   2755                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
   2756             }
   2757             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
   2758                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
   2759             }
   2760             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
   2761                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
   2762             }
   2763             if ("1".equals(SystemProperties.get("debug.assert"))) {
   2764                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
   2765             }
   2766 
   2767             // Start the process.  It will either succeed and return a result containing
   2768             // the PID of the new process, or else throw a RuntimeException.
   2769             Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
   2770                     app.processName, uid, uid, gids, debugFlags, mountExternal,
   2771                     app.info.targetSdkVersion, app.info.seinfo, null);
   2772 
   2773             BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   2774             synchronized (bs) {
   2775                 if (bs.isOnBattery()) {
   2776                     bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
   2777                 }
   2778             }
   2779 
   2780             EventLog.writeEvent(EventLogTags.AM_PROC_START,
   2781                     UserHandle.getUserId(uid), startResult.pid, uid,
   2782                     app.processName, hostingType,
   2783                     hostingNameStr != null ? hostingNameStr : "");
   2784 
   2785             if (app.persistent) {
   2786                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
   2787             }
   2788 
   2789             StringBuilder buf = mStringBuilder;
   2790             buf.setLength(0);
   2791             buf.append("Start proc ");
   2792             buf.append(app.processName);
   2793             buf.append(" for ");
   2794             buf.append(hostingType);
   2795             if (hostingNameStr != null) {
   2796                 buf.append(" ");
   2797                 buf.append(hostingNameStr);
   2798             }
   2799             buf.append(": pid=");
   2800             buf.append(startResult.pid);
   2801             buf.append(" uid=");
   2802             buf.append(uid);
   2803             buf.append(" gids={");
   2804             if (gids != null) {
   2805                 for (int gi=0; gi<gids.length; gi++) {
   2806                     if (gi != 0) buf.append(", ");
   2807                     buf.append(gids[gi]);
   2808 
   2809                 }
   2810             }
   2811             buf.append("}");
   2812             Slog.i(TAG, buf.toString());
   2813             app.setPid(startResult.pid);
   2814             app.usingWrapper = startResult.usingWrapper;
   2815             app.removed = false;
   2816             synchronized (mPidsSelfLocked) {
   2817                 this.mPidsSelfLocked.put(startResult.pid, app);
   2818                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
   2819                 msg.obj = app;
   2820                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
   2821                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
   2822             }
   2823         } catch (RuntimeException e) {
   2824             // XXX do better error recovery.
   2825             app.setPid(0);
   2826             Slog.e(TAG, "Failure starting process " + app.processName, e);
   2827         }
   2828     }
   2829 
   2830     void updateUsageStats(ActivityRecord component, boolean resumed) {
   2831         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
   2832         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   2833         if (resumed) {
   2834             mUsageStatsService.noteResumeComponent(component.realActivity);
   2835             synchronized (stats) {
   2836                 stats.noteActivityResumedLocked(component.app.uid);
   2837             }
   2838         } else {
   2839             mUsageStatsService.notePauseComponent(component.realActivity);
   2840             synchronized (stats) {
   2841                 stats.noteActivityPausedLocked(component.app.uid);
   2842             }
   2843         }
   2844     }
   2845 
   2846     Intent getHomeIntent() {
   2847         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
   2848         intent.setComponent(mTopComponent);
   2849         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   2850             intent.addCategory(Intent.CATEGORY_HOME);
   2851         }
   2852         return intent;
   2853     }
   2854 
   2855     boolean startHomeActivityLocked(int userId) {
   2856         if (mHeadless) {
   2857             // Added because none of the other calls to ensureBootCompleted seem to fire
   2858             // when running headless.
   2859             ensureBootCompleted();
   2860             return false;
   2861         }
   2862 
   2863         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
   2864                 && mTopAction == null) {
   2865             // We are running in factory test mode, but unable to find
   2866             // the factory test app, so just sit around displaying the
   2867             // error message and don't try to start anything.
   2868             return false;
   2869         }
   2870         Intent intent = getHomeIntent();
   2871         ActivityInfo aInfo =
   2872             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
   2873         if (aInfo != null) {
   2874             intent.setComponent(new ComponentName(
   2875                     aInfo.applicationInfo.packageName, aInfo.name));
   2876             // Don't do this if the home app is currently being
   2877             // instrumented.
   2878             aInfo = new ActivityInfo(aInfo);
   2879             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
   2880             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
   2881                     aInfo.applicationInfo.uid, true);
   2882             if (app == null || app.instrumentationClass == null) {
   2883                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
   2884                 mStackSupervisor.startHomeActivity(intent, aInfo);
   2885             }
   2886         }
   2887 
   2888         return true;
   2889     }
   2890 
   2891     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
   2892         ActivityInfo ai = null;
   2893         ComponentName comp = intent.getComponent();
   2894         try {
   2895             if (comp != null) {
   2896                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
   2897             } else {
   2898                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
   2899                         intent,
   2900                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
   2901                             flags, userId);
   2902 
   2903                 if (info != null) {
   2904                     ai = info.activityInfo;
   2905                 }
   2906             }
   2907         } catch (RemoteException e) {
   2908             // ignore
   2909         }
   2910 
   2911         return ai;
   2912     }
   2913 
   2914     /**
   2915      * Starts the "new version setup screen" if appropriate.
   2916      */
   2917     void startSetupActivityLocked() {
   2918         // Only do this once per boot.
   2919         if (mCheckedForSetup) {
   2920             return;
   2921         }
   2922 
   2923         // We will show this screen if the current one is a different
   2924         // version than the last one shown, and we are not running in
   2925         // low-level factory test mode.
   2926         final ContentResolver resolver = mContext.getContentResolver();
   2927         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
   2928                 Settings.Global.getInt(resolver,
   2929                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
   2930             mCheckedForSetup = true;
   2931 
   2932             // See if we should be showing the platform update setup UI.
   2933             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
   2934             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
   2935                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
   2936 
   2937             // We don't allow third party apps to replace this.
   2938             ResolveInfo ri = null;
   2939             for (int i=0; ris != null && i<ris.size(); i++) {
   2940                 if ((ris.get(i).activityInfo.applicationInfo.flags
   2941                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2942                     ri = ris.get(i);
   2943                     break;
   2944                 }
   2945             }
   2946 
   2947             if (ri != null) {
   2948                 String vers = ri.activityInfo.metaData != null
   2949                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
   2950                         : null;
   2951                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
   2952                     vers = ri.activityInfo.applicationInfo.metaData.getString(
   2953                             Intent.METADATA_SETUP_VERSION);
   2954                 }
   2955                 String lastVers = Settings.Secure.getString(
   2956                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
   2957                 if (vers != null && !vers.equals(lastVers)) {
   2958                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   2959                     intent.setComponent(new ComponentName(
   2960                             ri.activityInfo.packageName, ri.activityInfo.name));
   2961                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
   2962                             null, null, 0, 0, 0, null, 0, null, false, null);
   2963                 }
   2964             }
   2965         }
   2966     }
   2967 
   2968     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
   2969         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
   2970     }
   2971 
   2972     void enforceNotIsolatedCaller(String caller) {
   2973         if (UserHandle.isIsolated(Binder.getCallingUid())) {
   2974             throw new SecurityException("Isolated process not allowed to call " + caller);
   2975         }
   2976     }
   2977 
   2978     @Override
   2979     public int getFrontActivityScreenCompatMode() {
   2980         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
   2981         synchronized (this) {
   2982             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
   2983         }
   2984     }
   2985 
   2986     @Override
   2987     public void setFrontActivityScreenCompatMode(int mode) {
   2988         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   2989                 "setFrontActivityScreenCompatMode");
   2990         synchronized (this) {
   2991             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
   2992         }
   2993     }
   2994 
   2995     @Override
   2996     public int getPackageScreenCompatMode(String packageName) {
   2997         enforceNotIsolatedCaller("getPackageScreenCompatMode");
   2998         synchronized (this) {
   2999             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
   3000         }
   3001     }
   3002 
   3003     @Override
   3004     public void setPackageScreenCompatMode(String packageName, int mode) {
   3005         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3006                 "setPackageScreenCompatMode");
   3007         synchronized (this) {
   3008             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
   3009         }
   3010     }
   3011 
   3012     @Override
   3013     public boolean getPackageAskScreenCompat(String packageName) {
   3014         enforceNotIsolatedCaller("getPackageAskScreenCompat");
   3015         synchronized (this) {
   3016             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
   3017         }
   3018     }
   3019 
   3020     @Override
   3021     public void setPackageAskScreenCompat(String packageName, boolean ask) {
   3022         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
   3023                 "setPackageAskScreenCompat");
   3024         synchronized (this) {
   3025             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
   3026         }
   3027     }
   3028 
   3029     private void dispatchProcessesChanged() {
   3030         int N;
   3031         synchronized (this) {
   3032             N = mPendingProcessChanges.size();
   3033             if (mActiveProcessChanges.length < N) {
   3034                 mActiveProcessChanges = new ProcessChangeItem[N];
   3035             }
   3036             mPendingProcessChanges.toArray(mActiveProcessChanges);
   3037             mAvailProcessChanges.addAll(mPendingProcessChanges);
   3038             mPendingProcessChanges.clear();
   3039             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
   3040         }
   3041 
   3042         int i = mProcessObservers.beginBroadcast();
   3043         while (i > 0) {
   3044             i--;
   3045             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3046             if (observer != null) {
   3047                 try {
   3048                     for (int j=0; j<N; j++) {
   3049                         ProcessChangeItem item = mActiveProcessChanges[j];
   3050                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
   3051                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
   3052                                     + item.pid + " uid=" + item.uid + ": "
   3053                                     + item.foregroundActivities);
   3054                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
   3055                                     item.foregroundActivities);
   3056                         }
   3057                         if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
   3058                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
   3059                                     + item.pid + " uid=" + item.uid + ": " + item.importance);
   3060                             observer.onImportanceChanged(item.pid, item.uid,
   3061                                     item.importance);
   3062                         }
   3063                     }
   3064                 } catch (RemoteException e) {
   3065                 }
   3066             }
   3067         }
   3068         mProcessObservers.finishBroadcast();
   3069     }
   3070 
   3071     private void dispatchProcessDied(int pid, int uid) {
   3072         int i = mProcessObservers.beginBroadcast();
   3073         while (i > 0) {
   3074             i--;
   3075             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
   3076             if (observer != null) {
   3077                 try {
   3078                     observer.onProcessDied(pid, uid);
   3079                 } catch (RemoteException e) {
   3080                 }
   3081             }
   3082         }
   3083         mProcessObservers.finishBroadcast();
   3084     }
   3085 
   3086     final void doPendingActivityLaunchesLocked(boolean doResume) {
   3087         final int N = mPendingActivityLaunches.size();
   3088         if (N <= 0) {
   3089             return;
   3090         }
   3091         for (int i=0; i<N; i++) {
   3092             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
   3093             mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
   3094                     doResume && i == (N-1), null);
   3095         }
   3096         mPendingActivityLaunches.clear();
   3097     }
   3098 
   3099     @Override
   3100     public final int startActivity(IApplicationThread caller, String callingPackage,
   3101             Intent intent, String resolvedType, IBinder resultTo,
   3102             String resultWho, int requestCode, int startFlags,
   3103             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
   3104         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
   3105                 resultWho, requestCode,
   3106                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
   3107     }
   3108 
   3109     @Override
   3110     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
   3111             Intent intent, String resolvedType, IBinder resultTo,
   3112             String resultWho, int requestCode, int startFlags,
   3113             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
   3114         enforceNotIsolatedCaller("startActivity");
   3115         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3116                 false, true, "startActivity", null);
   3117         // TODO: Switch to user app stacks here.
   3118         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   3119                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   3120                 null, null, options, userId);
   3121     }
   3122 
   3123     @Override
   3124     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
   3125             Intent intent, String resolvedType, IBinder resultTo,
   3126             String resultWho, int requestCode, int startFlags, String profileFile,
   3127             ParcelFileDescriptor profileFd, Bundle options, int userId) {
   3128         enforceNotIsolatedCaller("startActivityAndWait");
   3129         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3130                 false, true, "startActivityAndWait", null);
   3131         WaitResult res = new WaitResult();
   3132         // TODO: Switch to user app stacks here.
   3133         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
   3134                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
   3135                 res, null, options, UserHandle.getCallingUserId());
   3136         return res;
   3137     }
   3138 
   3139     @Override
   3140     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
   3141             Intent intent, String resolvedType, IBinder resultTo,
   3142             String resultWho, int requestCode, int startFlags, Configuration config,
   3143             Bundle options, int userId) {
   3144         enforceNotIsolatedCaller("startActivityWithConfig");
   3145         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3146                 false, true, "startActivityWithConfig", null);
   3147         // TODO: Switch to user app stacks here.
   3148         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
   3149                 resolvedType, resultTo, resultWho, requestCode, startFlags,
   3150                 null, null, null, config, options, userId);
   3151         return ret;
   3152     }
   3153 
   3154     @Override
   3155     public int startActivityIntentSender(IApplicationThread caller,
   3156             IntentSender intent, Intent fillInIntent, String resolvedType,
   3157             IBinder resultTo, String resultWho, int requestCode,
   3158             int flagsMask, int flagsValues, Bundle options) {
   3159         enforceNotIsolatedCaller("startActivityIntentSender");
   3160         // Refuse possible leaked file descriptors
   3161         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
   3162             throw new IllegalArgumentException("File descriptors passed in Intent");
   3163         }
   3164 
   3165         IIntentSender sender = intent.getTarget();
   3166         if (!(sender instanceof PendingIntentRecord)) {
   3167             throw new IllegalArgumentException("Bad PendingIntent object");
   3168         }
   3169 
   3170         PendingIntentRecord pir = (PendingIntentRecord)sender;
   3171 
   3172         synchronized (this) {
   3173             // If this is coming from the currently resumed activity, it is
   3174             // effectively saying that app switches are allowed at this point.
   3175             final ActivityStack stack = getFocusedStack();
   3176             if (stack.mResumedActivity != null &&
   3177                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
   3178                 mAppSwitchesAllowedTime = 0;
   3179             }
   3180         }
   3181         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
   3182                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
   3183         return ret;
   3184     }
   3185 
   3186     @Override
   3187     public boolean startNextMatchingActivity(IBinder callingActivity,
   3188             Intent intent, Bundle options) {
   3189         // Refuse possible leaked file descriptors
   3190         if (intent != null && intent.hasFileDescriptors() == true) {
   3191             throw new IllegalArgumentException("File descriptors passed in Intent");
   3192         }
   3193 
   3194         synchronized (this) {
   3195             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
   3196             if (r == null) {
   3197                 ActivityOptions.abort(options);
   3198                 return false;
   3199             }
   3200             if (r.app == null || r.app.thread == null) {
   3201                 // The caller is not running...  d'oh!
   3202                 ActivityOptions.abort(options);
   3203                 return false;
   3204             }
   3205             intent = new Intent(intent);
   3206             // The caller is not allowed to change the data.
   3207             intent.setDataAndType(r.intent.getData(), r.intent.getType());
   3208             // And we are resetting to find the next component...
   3209             intent.setComponent(null);
   3210 
   3211             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3212 
   3213             ActivityInfo aInfo = null;
   3214             try {
   3215                 List<ResolveInfo> resolves =
   3216                     AppGlobals.getPackageManager().queryIntentActivities(
   3217                             intent, r.resolvedType,
   3218                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
   3219                             UserHandle.getCallingUserId());
   3220 
   3221                 // Look for the original activity in the list...
   3222                 final int N = resolves != null ? resolves.size() : 0;
   3223                 for (int i=0; i<N; i++) {
   3224                     ResolveInfo rInfo = resolves.get(i);
   3225                     if (rInfo.activityInfo.packageName.equals(r.packageName)
   3226                             && rInfo.activityInfo.name.equals(r.info.name)) {
   3227                         // We found the current one...  the next matching is
   3228                         // after it.
   3229                         i++;
   3230                         if (i<N) {
   3231                             aInfo = resolves.get(i).activityInfo;
   3232                         }
   3233                         if (debug) {
   3234                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
   3235                                     + "/" + r.info.name);
   3236                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
   3237                                     + "/" + aInfo.name);
   3238                         }
   3239                         break;
   3240                     }
   3241                 }
   3242             } catch (RemoteException e) {
   3243             }
   3244 
   3245             if (aInfo == null) {
   3246                 // Nobody who is next!
   3247                 ActivityOptions.abort(options);
   3248                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
   3249                 return false;
   3250             }
   3251 
   3252             intent.setComponent(new ComponentName(
   3253                     aInfo.applicationInfo.packageName, aInfo.name));
   3254             intent.setFlags(intent.getFlags()&~(
   3255                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
   3256                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
   3257                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
   3258                     Intent.FLAG_ACTIVITY_NEW_TASK));
   3259 
   3260             // Okay now we need to start the new activity, replacing the
   3261             // currently running activity.  This is a little tricky because
   3262             // we want to start the new one as if the current one is finished,
   3263             // but not finish the current one first so that there is no flicker.
   3264             // And thus...
   3265             final boolean wasFinishing = r.finishing;
   3266             r.finishing = true;
   3267 
   3268             // Propagate reply information over to the new activity.
   3269             final ActivityRecord resultTo = r.resultTo;
   3270             final String resultWho = r.resultWho;
   3271             final int requestCode = r.requestCode;
   3272             r.resultTo = null;
   3273             if (resultTo != null) {
   3274                 resultTo.removeResultsLocked(r, resultWho, requestCode);
   3275             }
   3276 
   3277             final long origId = Binder.clearCallingIdentity();
   3278             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
   3279                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
   3280                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
   3281                     options, false, null);
   3282             Binder.restoreCallingIdentity(origId);
   3283 
   3284             r.finishing = wasFinishing;
   3285             if (res != ActivityManager.START_SUCCESS) {
   3286                 return false;
   3287             }
   3288             return true;
   3289         }
   3290     }
   3291 
   3292     final int startActivityInPackage(int uid, String callingPackage,
   3293             Intent intent, String resolvedType, IBinder resultTo,
   3294             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
   3295 
   3296         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3297                 false, true, "startActivityInPackage", null);
   3298 
   3299         // TODO: Switch to user app stacks here.
   3300         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
   3301                 resultTo, resultWho, requestCode, startFlags,
   3302                 null, null, null, null, options, userId);
   3303         return ret;
   3304     }
   3305 
   3306     @Override
   3307     public final int startActivities(IApplicationThread caller, String callingPackage,
   3308             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
   3309             int userId) {
   3310         enforceNotIsolatedCaller("startActivities");
   3311         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3312                 false, true, "startActivity", null);
   3313         // TODO: Switch to user app stacks here.
   3314         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
   3315                 resolvedTypes, resultTo, options, userId);
   3316         return ret;
   3317     }
   3318 
   3319     final int startActivitiesInPackage(int uid, String callingPackage,
   3320             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
   3321             Bundle options, int userId) {
   3322 
   3323         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   3324                 false, true, "startActivityInPackage", null);
   3325         // TODO: Switch to user app stacks here.
   3326         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
   3327                 resultTo, options, userId);
   3328         return ret;
   3329     }
   3330 
   3331     final void addRecentTaskLocked(TaskRecord task) {
   3332         int N = mRecentTasks.size();
   3333         // Quick case: check if the top-most recent task is the same.
   3334         if (N > 0 && mRecentTasks.get(0) == task) {
   3335             return;
   3336         }
   3337         // Remove any existing entries that are the same kind of task.
   3338         for (int i=0; i<N; i++) {
   3339             TaskRecord tr = mRecentTasks.get(i);
   3340             if (task.userId == tr.userId
   3341                     && ((task.affinity != null && task.affinity.equals(tr.affinity))
   3342                     || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
   3343                 tr.disposeThumbnail();
   3344                 mRecentTasks.remove(i);
   3345                 i--;
   3346                 N--;
   3347                 if (task.intent == null) {
   3348                     // If the new recent task we are adding is not fully
   3349                     // specified, then replace it with the existing recent task.
   3350                     task = tr;
   3351                 }
   3352             }
   3353         }
   3354         if (N >= MAX_RECENT_TASKS) {
   3355             mRecentTasks.remove(N-1).disposeThumbnail();
   3356         }
   3357         mRecentTasks.add(0, task);
   3358     }
   3359 
   3360     @Override
   3361     public void reportActivityFullyDrawn(IBinder token) {
   3362         synchronized (this) {
   3363             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3364             if (r == null) {
   3365                 return;
   3366             }
   3367             r.reportFullyDrawnLocked();
   3368         }
   3369     }
   3370 
   3371     @Override
   3372     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
   3373         synchronized (this) {
   3374             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3375             if (r == null) {
   3376                 return;
   3377             }
   3378             final long origId = Binder.clearCallingIdentity();
   3379             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
   3380             Configuration config = mWindowManager.updateOrientationFromAppTokens(
   3381                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
   3382             if (config != null) {
   3383                 r.frozenBeforeDestroy = true;
   3384                 if (!updateConfigurationLocked(config, r, false, false)) {
   3385                     mStackSupervisor.resumeTopActivitiesLocked();
   3386                 }
   3387             }
   3388             Binder.restoreCallingIdentity(origId);
   3389         }
   3390     }
   3391 
   3392     @Override
   3393     public int getRequestedOrientation(IBinder token) {
   3394         synchronized (this) {
   3395             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3396             if (r == null) {
   3397                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
   3398             }
   3399             return mWindowManager.getAppOrientation(r.appToken);
   3400         }
   3401     }
   3402 
   3403     /**
   3404      * This is the internal entry point for handling Activity.finish().
   3405      *
   3406      * @param token The Binder token referencing the Activity we want to finish.
   3407      * @param resultCode Result code, if any, from this Activity.
   3408      * @param resultData Result data (Intent), if any, from this Activity.
   3409      *
   3410      * @return Returns true if the activity successfully finished, or false if it is still running.
   3411      */
   3412     @Override
   3413     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
   3414         // Refuse possible leaked file descriptors
   3415         if (resultData != null && resultData.hasFileDescriptors() == true) {
   3416             throw new IllegalArgumentException("File descriptors passed in Intent");
   3417         }
   3418 
   3419         synchronized(this) {
   3420             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3421             if (r == null) {
   3422                 return true;
   3423             }
   3424             if (mController != null) {
   3425                 // Find the first activity that is not finishing.
   3426                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
   3427                 if (next != null) {
   3428                     // ask watcher if this is allowed
   3429                     boolean resumeOK = true;
   3430                     try {
   3431                         resumeOK = mController.activityResuming(next.packageName);
   3432                     } catch (RemoteException e) {
   3433                         mController = null;
   3434                         Watchdog.getInstance().setActivityController(null);
   3435                     }
   3436 
   3437                     if (!resumeOK) {
   3438                         return false;
   3439                     }
   3440                 }
   3441             }
   3442             final long origId = Binder.clearCallingIdentity();
   3443             boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
   3444                     resultData, "app-request", true);
   3445             Binder.restoreCallingIdentity(origId);
   3446             return res;
   3447         }
   3448     }
   3449 
   3450     @Override
   3451     public final void finishHeavyWeightApp() {
   3452         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3453                 != PackageManager.PERMISSION_GRANTED) {
   3454             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
   3455                     + Binder.getCallingPid()
   3456                     + ", uid=" + Binder.getCallingUid()
   3457                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3458             Slog.w(TAG, msg);
   3459             throw new SecurityException(msg);
   3460         }
   3461 
   3462         synchronized(this) {
   3463             if (mHeavyWeightProcess == null) {
   3464                 return;
   3465             }
   3466 
   3467             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
   3468                     mHeavyWeightProcess.activities);
   3469             for (int i=0; i<activities.size(); i++) {
   3470                 ActivityRecord r = activities.get(i);
   3471                 if (!r.finishing) {
   3472                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
   3473                             null, "finish-heavy", true);
   3474                 }
   3475             }
   3476 
   3477             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   3478                     mHeavyWeightProcess.userId, 0));
   3479             mHeavyWeightProcess = null;
   3480         }
   3481     }
   3482 
   3483     @Override
   3484     public void crashApplication(int uid, int initialPid, String packageName,
   3485             String message) {
   3486         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   3487                 != PackageManager.PERMISSION_GRANTED) {
   3488             String msg = "Permission Denial: crashApplication() from pid="
   3489                     + Binder.getCallingPid()
   3490                     + ", uid=" + Binder.getCallingUid()
   3491                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   3492             Slog.w(TAG, msg);
   3493             throw new SecurityException(msg);
   3494         }
   3495 
   3496         synchronized(this) {
   3497             ProcessRecord proc = null;
   3498 
   3499             // Figure out which process to kill.  We don't trust that initialPid
   3500             // still has any relation to current pids, so must scan through the
   3501             // list.
   3502             synchronized (mPidsSelfLocked) {
   3503                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   3504                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
   3505                     if (p.uid != uid) {
   3506                         continue;
   3507                     }
   3508                     if (p.pid == initialPid) {
   3509                         proc = p;
   3510                         break;
   3511                     }
   3512                     if (p.pkgList.containsKey(packageName)) {
   3513                         proc = p;
   3514                     }
   3515                 }
   3516             }
   3517 
   3518             if (proc == null) {
   3519                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
   3520                         + " initialPid=" + initialPid
   3521                         + " packageName=" + packageName);
   3522                 return;
   3523             }
   3524 
   3525             if (proc.thread != null) {
   3526                 if (proc.pid == Process.myPid()) {
   3527                     Log.w(TAG, "crashApplication: trying to crash self!");
   3528                     return;
   3529                 }
   3530                 long ident = Binder.clearCallingIdentity();
   3531                 try {
   3532                     proc.thread.scheduleCrash(message);
   3533                 } catch (RemoteException e) {
   3534                 }
   3535                 Binder.restoreCallingIdentity(ident);
   3536             }
   3537         }
   3538     }
   3539 
   3540     @Override
   3541     public final void finishSubActivity(IBinder token, String resultWho,
   3542             int requestCode) {
   3543         synchronized(this) {
   3544             final long origId = Binder.clearCallingIdentity();
   3545             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3546             if (r != null) {
   3547                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
   3548             }
   3549             Binder.restoreCallingIdentity(origId);
   3550         }
   3551     }
   3552 
   3553     @Override
   3554     public boolean finishActivityAffinity(IBinder token) {
   3555         synchronized(this) {
   3556             final long origId = Binder.clearCallingIdentity();
   3557             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   3558             boolean res = false;
   3559             if (r != null) {
   3560                 res = r.task.stack.finishActivityAffinityLocked(r);
   3561             }
   3562             Binder.restoreCallingIdentity(origId);
   3563             return res;
   3564         }
   3565     }
   3566 
   3567     @Override
   3568     public boolean willActivityBeVisible(IBinder token) {
   3569         synchronized(this) {
   3570             ActivityStack stack = ActivityRecord.getStackLocked(token);
   3571             if (stack != null) {
   3572                 return stack.willActivityBeVisibleLocked(token);
   3573             }
   3574             return false;
   3575         }
   3576     }
   3577 
   3578     @Override
   3579     public void overridePendingTransition(IBinder token, String packageName,
   3580             int enterAnim, int exitAnim) {
   3581         synchronized(this) {
   3582             ActivityRecord self = ActivityRecord.isInStackLocked(token);
   3583             if (self == null) {
   3584                 return;
   3585             }
   3586 
   3587             final long origId = Binder.clearCallingIdentity();
   3588 
   3589             if (self.state == ActivityState.RESUMED
   3590                     || self.state == ActivityState.PAUSING) {
   3591                 mWindowManager.overridePendingAppTransition(packageName,
   3592                         enterAnim, exitAnim, null);
   3593             }
   3594 
   3595             Binder.restoreCallingIdentity(origId);
   3596         }
   3597     }
   3598 
   3599     /**
   3600      * Main function for removing an existing process from the activity manager
   3601      * as a result of that process going away.  Clears out all connections
   3602      * to the process.
   3603      */
   3604     private final void handleAppDiedLocked(ProcessRecord app,
   3605             boolean restarting, boolean allowRestart) {
   3606         cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
   3607         if (!restarting) {
   3608             removeLruProcessLocked(app);
   3609         }
   3610 
   3611         if (mProfileProc == app) {
   3612             clearProfilerLocked();
   3613         }
   3614 
   3615         // Remove this application's activities from active lists.
   3616         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
   3617 
   3618         app.activities.clear();
   3619 
   3620         if (app.instrumentationClass != null) {
   3621             Slog.w(TAG, "Crash of app " + app.processName
   3622                   + " running instrumentation " + app.instrumentationClass);
   3623             Bundle info = new Bundle();
   3624             info.putString("shortMsg", "Process crashed.");
   3625             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
   3626         }
   3627 
   3628         if (!restarting) {
   3629             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
   3630                 // If there was nothing to resume, and we are not already
   3631                 // restarting this process, but there is a visible activity that
   3632                 // is hosted by the process...  then make sure all visible
   3633                 // activities are running, taking care of restarting this
   3634                 // process.
   3635                 if (hasVisibleActivities) {
   3636                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   3637                 }
   3638             }
   3639         }
   3640     }
   3641 
   3642     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
   3643         IBinder threadBinder = thread.asBinder();
   3644         // Find the application record.
   3645         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3646             ProcessRecord rec = mLruProcesses.get(i);
   3647             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
   3648                 return i;
   3649             }
   3650         }
   3651         return -1;
   3652     }
   3653 
   3654     final ProcessRecord getRecordForAppLocked(
   3655             IApplicationThread thread) {
   3656         if (thread == null) {
   3657             return null;
   3658         }
   3659 
   3660         int appIndex = getLRURecordIndexForAppLocked(thread);
   3661         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
   3662     }
   3663 
   3664     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
   3665         // If there are no longer any background processes running,
   3666         // and the app that died was not running instrumentation,
   3667         // then tell everyone we are now low on memory.
   3668         boolean haveBg = false;
   3669         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3670             ProcessRecord rec = mLruProcesses.get(i);
   3671             if (rec.thread != null
   3672                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   3673                 haveBg = true;
   3674                 break;
   3675             }
   3676         }
   3677 
   3678         if (!haveBg) {
   3679             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   3680             if (doReport) {
   3681                 long now = SystemClock.uptimeMillis();
   3682                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
   3683                     doReport = false;
   3684                 } else {
   3685                     mLastMemUsageReportTime = now;
   3686                 }
   3687             }
   3688             final ArrayList<ProcessMemInfo> memInfos
   3689                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
   3690             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
   3691             long now = SystemClock.uptimeMillis();
   3692             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   3693                 ProcessRecord rec = mLruProcesses.get(i);
   3694                 if (rec == dyingProc || rec.thread == null) {
   3695                     continue;
   3696                 }
   3697                 if (doReport) {
   3698                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
   3699                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
   3700                 }
   3701                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
   3702                     // The low memory report is overriding any current
   3703                     // state for a GC request.  Make sure to do
   3704                     // heavy/important/visible/foreground processes first.
   3705                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   3706                         rec.lastRequestedGc = 0;
   3707                     } else {
   3708                         rec.lastRequestedGc = rec.lastLowMemory;
   3709                     }
   3710                     rec.reportLowMemory = true;
   3711                     rec.lastLowMemory = now;
   3712                     mProcessesToGc.remove(rec);
   3713                     addProcessToGcListLocked(rec);
   3714                 }
   3715             }
   3716             if (doReport) {
   3717                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
   3718                 mHandler.sendMessage(msg);
   3719             }
   3720             scheduleAppGcsLocked();
   3721         }
   3722     }
   3723 
   3724     final void appDiedLocked(ProcessRecord app, int pid,
   3725             IApplicationThread thread) {
   3726 
   3727         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   3728         synchronized (stats) {
   3729             stats.noteProcessDiedLocked(app.info.uid, pid);
   3730         }
   3731 
   3732         // Clean up already done if the process has been re-started.
   3733         if (app.pid == pid && app.thread != null &&
   3734                 app.thread.asBinder() == thread.asBinder()) {
   3735             boolean doLowMem = app.instrumentationClass == null;
   3736             boolean doOomAdj = doLowMem;
   3737             if (!app.killedByAm) {
   3738                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3739                         + ") has died.");
   3740                 mAllowLowerMemLevel = true;
   3741             } else {
   3742                 // Note that we always want to do oom adj to update our state with the
   3743                 // new number of procs.
   3744                 mAllowLowerMemLevel = false;
   3745                 doLowMem = false;
   3746             }
   3747             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3748             if (DEBUG_CLEANUP) Slog.v(
   3749                 TAG, "Dying app: " + app + ", pid: " + pid
   3750                 + ", thread: " + thread.asBinder());
   3751             handleAppDiedLocked(app, false, true);
   3752 
   3753             if (doOomAdj) {
   3754                 updateOomAdjLocked();
   3755             }
   3756             if (doLowMem) {
   3757                 doLowMemReportIfNeededLocked(app);
   3758             }
   3759         } else if (app.pid != pid) {
   3760             // A new process has already been started.
   3761             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
   3762                     + ") has died and restarted (pid " + app.pid + ").");
   3763             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
   3764         } else if (DEBUG_PROCESSES) {
   3765             Slog.d(TAG, "Received spurious death notification for thread "
   3766                     + thread.asBinder());
   3767         }
   3768     }
   3769 
   3770     /**
   3771      * If a stack trace dump file is configured, dump process stack traces.
   3772      * @param clearTraces causes the dump file to be erased prior to the new
   3773      *    traces being written, if true; when false, the new traces will be
   3774      *    appended to any existing file content.
   3775      * @param firstPids of dalvik VM processes to dump stack traces for first
   3776      * @param lastPids of dalvik VM processes to dump stack traces for last
   3777      * @param nativeProcs optional list of native process names to dump stack crawls
   3778      * @return file containing stack traces, or null if no dump file is configured
   3779      */
   3780     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
   3781             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3782         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3783         if (tracesPath == null || tracesPath.length() == 0) {
   3784             return null;
   3785         }
   3786 
   3787         File tracesFile = new File(tracesPath);
   3788         try {
   3789             File tracesDir = tracesFile.getParentFile();
   3790             if (!tracesDir.exists()) {
   3791                 tracesFile.mkdirs();
   3792                 if (!SELinux.restorecon(tracesDir)) {
   3793                     return null;
   3794                 }
   3795             }
   3796             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3797 
   3798             if (clearTraces && tracesFile.exists()) tracesFile.delete();
   3799             tracesFile.createNewFile();
   3800             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3801         } catch (IOException e) {
   3802             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
   3803             return null;
   3804         }
   3805 
   3806         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
   3807         return tracesFile;
   3808     }
   3809 
   3810     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
   3811             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
   3812         // Use a FileObserver to detect when traces finish writing.
   3813         // The order of traces is considered important to maintain for legibility.
   3814         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
   3815             @Override
   3816             public synchronized void onEvent(int event, String path) { notify(); }
   3817         };
   3818 
   3819         try {
   3820             observer.startWatching();
   3821 
   3822             // First collect all of the stacks of the most important pids.
   3823             if (firstPids != null) {
   3824                 try {
   3825                     int num = firstPids.size();
   3826                     for (int i = 0; i < num; i++) {
   3827                         synchronized (observer) {
   3828                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
   3829                             observer.wait(200);  // Wait for write-close, give up after 200msec
   3830                         }
   3831                     }
   3832                 } catch (InterruptedException e) {
   3833                     Log.wtf(TAG, e);
   3834                 }
   3835             }
   3836 
   3837             // Next collect the stacks of the native pids
   3838             if (nativeProcs != null) {
   3839                 int[] pids = Process.getPidsForCommands(nativeProcs);
   3840                 if (pids != null) {
   3841                     for (int pid : pids) {
   3842                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
   3843                     }
   3844                 }
   3845             }
   3846 
   3847             // Lastly, measure CPU usage.
   3848             if (processCpuTracker != null) {
   3849                 processCpuTracker.init();
   3850                 System.gc();
   3851                 processCpuTracker.update();
   3852                 try {
   3853                     synchronized (processCpuTracker) {
   3854                         processCpuTracker.wait(500); // measure over 1/2 second.
   3855                     }
   3856                 } catch (InterruptedException e) {
   3857                 }
   3858                 processCpuTracker.update();
   3859 
   3860                 // We'll take the stack crawls of just the top apps using CPU.
   3861                 final int N = processCpuTracker.countWorkingStats();
   3862                 int numProcs = 0;
   3863                 for (int i=0; i<N && numProcs<5; i++) {
   3864                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
   3865                     if (lastPids.indexOfKey(stats.pid) >= 0) {
   3866                         numProcs++;
   3867                         try {
   3868                             synchronized (observer) {
   3869                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
   3870                                 observer.wait(200);  // Wait for write-close, give up after 200msec
   3871                             }
   3872                         } catch (InterruptedException e) {
   3873                             Log.wtf(TAG, e);
   3874                         }
   3875 
   3876                     }
   3877                 }
   3878             }
   3879         } finally {
   3880             observer.stopWatching();
   3881         }
   3882     }
   3883 
   3884     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
   3885         if (true || IS_USER_BUILD) {
   3886             return;
   3887         }
   3888         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
   3889         if (tracesPath == null || tracesPath.length() == 0) {
   3890             return;
   3891         }
   3892 
   3893         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
   3894         StrictMode.allowThreadDiskWrites();
   3895         try {
   3896             final File tracesFile = new File(tracesPath);
   3897             final File tracesDir = tracesFile.getParentFile();
   3898             final File tracesTmp = new File(tracesDir, "__tmp__");
   3899             try {
   3900                 if (!tracesDir.exists()) {
   3901                     tracesFile.mkdirs();
   3902                     if (!SELinux.restorecon(tracesDir.getPath())) {
   3903                         return;
   3904                     }
   3905                 }
   3906                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
   3907 
   3908                 if (tracesFile.exists()) {
   3909                     tracesTmp.delete();
   3910                     tracesFile.renameTo(tracesTmp);
   3911                 }
   3912                 StringBuilder sb = new StringBuilder();
   3913                 Time tobj = new Time();
   3914                 tobj.set(System.currentTimeMillis());
   3915                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
   3916                 sb.append(": ");
   3917                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
   3918                 sb.append(" since ");
   3919                 sb.append(msg);
   3920                 FileOutputStream fos = new FileOutputStream(tracesFile);
   3921                 fos.write(sb.toString().getBytes());
   3922                 if (app == null) {
   3923                     fos.write("\n*** No application process!".getBytes());
   3924                 }
   3925                 fos.close();
   3926                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
   3927             } catch (IOException e) {
   3928                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
   3929                 return;
   3930             }
   3931 
   3932             if (app != null) {
   3933                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
   3934                 firstPids.add(app.pid);
   3935                 dumpStackTraces(tracesPath, firstPids, null, null, null);
   3936             }
   3937 
   3938             File lastTracesFile = null;
   3939             File curTracesFile = null;
   3940             for (int i=9; i>=0; i--) {
   3941                 String name = String.format(Locale.US, "slow%02d.txt", i);
   3942                 curTracesFile = new File(tracesDir, name);
   3943                 if (curTracesFile.exists()) {
   3944                     if (lastTracesFile != null) {
   3945                         curTracesFile.renameTo(lastTracesFile);
   3946                     } else {
   3947                         curTracesFile.delete();
   3948                     }
   3949                 }
   3950                 lastTracesFile = curTracesFile;
   3951             }
   3952             tracesFile.renameTo(curTracesFile);
   3953             if (tracesTmp.exists()) {
   3954                 tracesTmp.renameTo(tracesFile);
   3955             }
   3956         } finally {
   3957             StrictMode.setThreadPolicy(oldPolicy);
   3958         }
   3959     }
   3960 
   3961     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
   3962             ActivityRecord parent, boolean aboveSystem, final String annotation) {
   3963         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
   3964         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
   3965 
   3966         if (mController != null) {
   3967             try {
   3968                 // 0 == continue, -1 = kill process immediately
   3969                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
   3970                 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
   3971             } catch (RemoteException e) {
   3972                 mController = null;
   3973                 Watchdog.getInstance().setActivityController(null);
   3974             }
   3975         }
   3976 
   3977         long anrTime = SystemClock.uptimeMillis();
   3978         if (MONITOR_CPU_USAGE) {
   3979             updateCpuStatsNow();
   3980         }
   3981 
   3982         synchronized (this) {
   3983             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
   3984             if (mShuttingDown) {
   3985                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
   3986                 return;
   3987             } else if (app.notResponding) {
   3988                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
   3989                 return;
   3990             } else if (app.crashing) {
   3991                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
   3992                 return;
   3993             }
   3994 
   3995             // In case we come through here for the same app before completing
   3996             // this one, mark as anring now so we will bail out.
   3997             app.notResponding = true;
   3998 
   3999             // Log the ANR to the event log.
   4000             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
   4001                     app.processName, app.info.flags, annotation);
   4002 
   4003             // Dump thread traces as quickly as we can, starting with "interesting" processes.
   4004             firstPids.add(app.pid);
   4005 
   4006             int parentPid = app.pid;
   4007             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
   4008             if (parentPid != app.pid) firstPids.add(parentPid);
   4009 
   4010             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
   4011 
   4012             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   4013                 ProcessRecord r = mLruProcesses.get(i);
   4014                 if (r != null && r.thread != null) {
   4015                     int pid = r.pid;
   4016                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
   4017                         if (r.persistent) {
   4018                             firstPids.add(pid);
   4019                         } else {
   4020                             lastPids.put(pid, Boolean.TRUE);
   4021                         }
   4022                     }
   4023                 }
   4024             }
   4025         }
   4026 
   4027         // Log the ANR to the main log.
   4028         StringBuilder info = new StringBuilder();
   4029         info.setLength(0);
   4030         info.append("ANR in ").append(app.processName);
   4031         if (activity != null && activity.shortComponentName != null) {
   4032             info.append(" (").append(activity.shortComponentName).append(")");
   4033         }
   4034         info.append("\n");
   4035         info.append("PID: ").append(app.pid).append("\n");
   4036         if (annotation != null) {
   4037             info.append("Reason: ").append(annotation).append("\n");
   4038         }
   4039         if (parent != null && parent != activity) {
   4040             info.append("Parent: ").append(parent.shortComponentName).append("\n");
   4041         }
   4042 
   4043         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
   4044 
   4045         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
   4046                 NATIVE_STACKS_OF_INTEREST);
   4047 
   4048         String cpuInfo = null;
   4049         if (MONITOR_CPU_USAGE) {
   4050             updateCpuStatsNow();
   4051             synchronized (mProcessCpuThread) {
   4052                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
   4053             }
   4054             info.append(processCpuTracker.printCurrentLoad());
   4055             info.append(cpuInfo);
   4056         }
   4057 
   4058         info.append(processCpuTracker.printCurrentState(anrTime));
   4059 
   4060         Slog.e(TAG, info.toString());
   4061         if (tracesFile == null) {
   4062             // There is no trace file, so dump (only) the alleged culprit's threads to the log
   4063             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
   4064         }
   4065 
   4066         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
   4067                 cpuInfo, tracesFile, null);
   4068 
   4069         if (mController != null) {
   4070             try {
   4071                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
   4072                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
   4073                 if (res != 0) {
   4074                     if (res < 0 && app.pid != MY_PID) {
   4075                         Process.killProcess(app.pid);
   4076                     } else {
   4077                         synchronized (this) {
   4078                             mServices.scheduleServiceTimeoutLocked(app);
   4079                         }
   4080                     }
   4081                     return;
   4082                 }
   4083             } catch (RemoteException e) {
   4084                 mController = null;
   4085                 Watchdog.getInstance().setActivityController(null);
   4086             }
   4087         }
   4088 
   4089         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
   4090         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
   4091                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
   4092 
   4093         synchronized (this) {
   4094             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
   4095                 killUnneededProcessLocked(app, "background ANR");
   4096                 return;
   4097             }
   4098 
   4099             // Set the app's notResponding state, and look up the errorReportReceiver
   4100             makeAppNotRespondingLocked(app,
   4101                     activity != null ? activity.shortComponentName : null,
   4102                     annotation != null ? "ANR " + annotation : "ANR",
   4103                     info.toString());
   4104 
   4105             // Bring up the infamous App Not Responding dialog
   4106             Message msg = Message.obtain();
   4107             HashMap<String, Object> map = new HashMap<String, Object>();
   4108             msg.what = SHOW_NOT_RESPONDING_MSG;
   4109             msg.obj = map;
   4110             msg.arg1 = aboveSystem ? 1 : 0;
   4111             map.put("app", app);
   4112             if (activity != null) {
   4113                 map.put("activity", activity);
   4114             }
   4115 
   4116             mHandler.sendMessage(msg);
   4117         }
   4118     }
   4119 
   4120     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
   4121         if (!mLaunchWarningShown) {
   4122             mLaunchWarningShown = true;
   4123             mHandler.post(new Runnable() {
   4124                 @Override
   4125                 public void run() {
   4126                     synchronized (ActivityManagerService.this) {
   4127                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
   4128                         d.show();
   4129                         mHandler.postDelayed(new Runnable() {
   4130                             @Override
   4131                             public void run() {
   4132                                 synchronized (ActivityManagerService.this) {
   4133                                     d.dismiss();
   4134                                     mLaunchWarningShown = false;
   4135                                 }
   4136                             }
   4137                         }, 4000);
   4138                     }
   4139                 }
   4140             });
   4141         }
   4142     }
   4143 
   4144     @Override
   4145     public boolean clearApplicationUserData(final String packageName,
   4146             final IPackageDataObserver observer, int userId) {
   4147         enforceNotIsolatedCaller("clearApplicationUserData");
   4148         int uid = Binder.getCallingUid();
   4149         int pid = Binder.getCallingPid();
   4150         userId = handleIncomingUser(pid, uid,
   4151                 userId, false, true, "clearApplicationUserData", null);
   4152         long callingId = Binder.clearCallingIdentity();
   4153         try {
   4154             IPackageManager pm = AppGlobals.getPackageManager();
   4155             int pkgUid = -1;
   4156             synchronized(this) {
   4157                 try {
   4158                     pkgUid = pm.getPackageUid(packageName, userId);
   4159                 } catch (RemoteException e) {
   4160                 }
   4161                 if (pkgUid == -1) {
   4162                     Slog.w(TAG, "Invalid packageName: " + packageName);
   4163                     if (observer != null) {
   4164                         try {
   4165                             observer.onRemoveCompleted(packageName, false);
   4166                         } catch (RemoteException e) {
   4167                             Slog.i(TAG, "Observer no longer exists.");
   4168                         }
   4169                     }
   4170                     return false;
   4171                 }
   4172                 if (uid == pkgUid || checkComponentPermission(
   4173                         android.Manifest.permission.CLEAR_APP_USER_DATA,
   4174                         pid, uid, -1, true)
   4175                         == PackageManager.PERMISSION_GRANTED) {
   4176                     forceStopPackageLocked(packageName, pkgUid, "clear data");
   4177                 } else {
   4178                     throw new SecurityException(pid+" does not have permission:"+
   4179                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
   4180                                     "for process:"+packageName);
   4181                 }
   4182             }
   4183 
   4184             try {
   4185                 // Clear application user data
   4186                 pm.clearApplicationUserData(packageName, observer, userId);
   4187 
   4188                 // Remove all permissions granted from/to this package
   4189                 removeUriPermissionsForPackageLocked(packageName, userId, true);
   4190 
   4191                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
   4192                         Uri.fromParts("package", packageName, null));
   4193                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
   4194                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
   4195                         null, null, 0, null, null, null, false, false, userId);
   4196             } catch (RemoteException e) {
   4197             }
   4198         } finally {
   4199             Binder.restoreCallingIdentity(callingId);
   4200         }
   4201         return true;
   4202     }
   4203 
   4204     @Override
   4205     public void killBackgroundProcesses(final String packageName, int userId) {
   4206         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   4207                 != PackageManager.PERMISSION_GRANTED &&
   4208                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
   4209                         != PackageManager.PERMISSION_GRANTED) {
   4210             String msg = "Permission Denial: killBackgroundProcesses() from pid="
   4211                     + Binder.getCallingPid()
   4212                     + ", uid=" + Binder.getCallingUid()
   4213                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   4214             Slog.w(TAG, msg);
   4215             throw new SecurityException(msg);
   4216         }
   4217 
   4218         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   4219                 userId, true, true, "killBackgroundProcesses", null);
   4220         long callingId = Binder.clearCallingIdentity();
   4221         try {
   4222             IPackageManager pm = AppGlobals.getPackageManager();
   4223             synchronized(this) {
   4224                 int appId = -1;
   4225                 try {
   4226                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
   4227                 } catch (RemoteException e) {
   4228                 }
   4229                 if (appId == -1) {
   4230                     Slog.w(TAG, "Invalid packageName: " + packageName);
   4231                     return;
   4232                 }
   4233                 killPackageProcessesLocked(packageName, appId, userId,
   4234                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
   4235             }
   4236         } finally {
   4237             Binder.restoreCallingIdentity(callingId);
   4238         }
   4239     }
   4240 
   4241     @Override
   4242     public void killAllBackgroundProcesses() {
   4243         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
   4244                 != PackageManager.PERMISSION_GRANTED) {
   4245             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
   4246                     + Binder.getCallingPid()
   4247                     + ", uid=" + Binder.getCallingUid()
   4248                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
   4249             Slog.w(TAG, msg);
   4250             throw new SecurityException(msg);
   4251         }
   4252 
   4253         long callingId = Binder.clearCallingIdentity();
   4254         try {
   4255             synchronized(this) {
   4256                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   4257                 final int NP = mProcessNames.getMap().size();
   4258                 for (int ip=0; ip<NP; ip++) {
   4259                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   4260                     final int NA = apps.size();
   4261                     for (int ia=0; ia<NA; ia++) {
   4262                         ProcessRecord app = apps.valueAt(ia);
   4263                         if (app.persistent) {
   4264                             // we don't kill persistent processes
   4265                             continue;
   4266                         }
   4267                         if (app.removed) {
   4268                             procs.add(app);
   4269                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   4270                             app.removed = true;
   4271                             procs.add(app);
   4272                         }
   4273                     }
   4274                 }
   4275 
   4276                 int N = procs.size();
   4277                 for (int i=0; i<N; i++) {
   4278                     removeProcessLocked(procs.get(i), false, true, "kill all background");
   4279                 }
   4280                 mAllowLowerMemLevel = true;
   4281                 updateOomAdjLocked();
   4282                 doLowMemReportIfNeededLocked(null);
   4283             }
   4284         } finally {
   4285             Binder.restoreCallingIdentity(callingId);
   4286         }
   4287     }
   4288 
   4289     @Override
   4290     public void forceStopPackage(final String packageName, int userId) {
   4291         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
   4292                 != PackageManager.PERMISSION_GRANTED) {
   4293             String msg = "Permission Denial: forceStopPackage() from pid="
   4294                     + Binder.getCallingPid()
   4295                     + ", uid=" + Binder.getCallingUid()
   4296                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
   4297             Slog.w(TAG, msg);
   4298             throw new SecurityException(msg);
   4299         }
   4300         final int callingPid = Binder.getCallingPid();
   4301         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
   4302                 userId, true, true, "forceStopPackage", null);
   4303         long callingId = Binder.clearCallingIdentity();
   4304         try {
   4305             IPackageManager pm = AppGlobals.getPackageManager();
   4306             synchronized(this) {
   4307                 int[] users = userId == UserHandle.USER_ALL
   4308                         ? getUsersLocked() : new int[] { userId };
   4309                 for (int user : users) {
   4310                     int pkgUid = -1;
   4311                     try {
   4312                         pkgUid = pm.getPackageUid(packageName, user);
   4313                     } catch (RemoteException e) {
   4314                     }
   4315                     if (pkgUid == -1) {
   4316                         Slog.w(TAG, "Invalid packageName: " + packageName);
   4317                         continue;
   4318                     }
   4319                     try {
   4320                         pm.setPackageStoppedState(packageName, true, user);
   4321                     } catch (RemoteException e) {
   4322                     } catch (IllegalArgumentException e) {
   4323                         Slog.w(TAG, "Failed trying to unstop package "
   4324                                 + packageName + ": " + e);
   4325                     }
   4326                     if (isUserRunningLocked(user, false)) {
   4327                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
   4328                     }
   4329                 }
   4330             }
   4331         } finally {
   4332             Binder.restoreCallingIdentity(callingId);
   4333         }
   4334     }
   4335 
   4336     /*
   4337      * The pkg name and app id have to be specified.
   4338      */
   4339     @Override
   4340     public void killApplicationWithAppId(String pkg, int appid, String reason) {
   4341         if (pkg == null) {
   4342             return;
   4343         }
   4344         // Make sure the uid is valid.
   4345         if (appid < 0) {
   4346             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
   4347             return;
   4348         }
   4349         int callerUid = Binder.getCallingUid();
   4350         // Only the system server can kill an application
   4351         if (callerUid == Process.SYSTEM_UID) {
   4352             // Post an aysnc message to kill the application
   4353             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
   4354             msg.arg1 = appid;
   4355             msg.arg2 = 0;
   4356             Bundle bundle = new Bundle();
   4357             bundle.putString("pkg", pkg);
   4358             bundle.putString("reason", reason);
   4359             msg.obj = bundle;
   4360             mHandler.sendMessage(msg);
   4361         } else {
   4362             throw new SecurityException(callerUid + " cannot kill pkg: " +
   4363                     pkg);
   4364         }
   4365     }
   4366 
   4367     @Override
   4368     public void closeSystemDialogs(String reason) {
   4369         enforceNotIsolatedCaller("closeSystemDialogs");
   4370 
   4371         final int pid = Binder.getCallingPid();
   4372         final int uid = Binder.getCallingUid();
   4373         final long origId = Binder.clearCallingIdentity();
   4374         try {
   4375             synchronized (this) {
   4376                 // Only allow this from foreground processes, so that background
   4377                 // applications can't abuse it to prevent system UI from being shown.
   4378                 if (uid >= Process.FIRST_APPLICATION_UID) {
   4379                     ProcessRecord proc;
   4380                     synchronized (mPidsSelfLocked) {
   4381                         proc = mPidsSelfLocked.get(pid);
   4382                     }
   4383                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   4384                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
   4385                                 + " from background process " + proc);
   4386                         return;
   4387                     }
   4388                 }
   4389                 closeSystemDialogsLocked(reason);
   4390             }
   4391         } finally {
   4392             Binder.restoreCallingIdentity(origId);
   4393         }
   4394     }
   4395 
   4396     void closeSystemDialogsLocked(String reason) {
   4397         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
   4398         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4399                 | Intent.FLAG_RECEIVER_FOREGROUND);
   4400         if (reason != null) {
   4401             intent.putExtra("reason", reason);
   4402         }
   4403         mWindowManager.closeSystemDialogs(reason);
   4404 
   4405         mStackSupervisor.closeSystemDialogsLocked();
   4406 
   4407         broadcastIntentLocked(null, null, intent, null,
   4408                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
   4409                 Process.SYSTEM_UID, UserHandle.USER_ALL);
   4410     }
   4411 
   4412     @Override
   4413     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
   4414         enforceNotIsolatedCaller("getProcessMemoryInfo");
   4415         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
   4416         for (int i=pids.length-1; i>=0; i--) {
   4417             ProcessRecord proc;
   4418             int oomAdj;
   4419             synchronized (this) {
   4420                 synchronized (mPidsSelfLocked) {
   4421                     proc = mPidsSelfLocked.get(pids[i]);
   4422                     oomAdj = proc != null ? proc.setAdj : 0;
   4423                 }
   4424             }
   4425             infos[i] = new Debug.MemoryInfo();
   4426             Debug.getMemoryInfo(pids[i], infos[i]);
   4427             if (proc != null) {
   4428                 synchronized (this) {
   4429                     if (proc.thread != null && proc.setAdj == oomAdj) {
   4430                         // Record this for posterity if the process has been stable.
   4431                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
   4432                                 infos[i].getTotalUss(), false, proc.pkgList);
   4433                     }
   4434                 }
   4435             }
   4436         }
   4437         return infos;
   4438     }
   4439 
   4440     @Override
   4441     public long[] getProcessPss(int[] pids) {
   4442         enforceNotIsolatedCaller("getProcessPss");
   4443         long[] pss = new long[pids.length];
   4444         for (int i=pids.length-1; i>=0; i--) {
   4445             ProcessRecord proc;
   4446             int oomAdj;
   4447             synchronized (this) {
   4448                 synchronized (mPidsSelfLocked) {
   4449                     proc = mPidsSelfLocked.get(pids[i]);
   4450                     oomAdj = proc != null ? proc.setAdj : 0;
   4451                 }
   4452             }
   4453             long[] tmpUss = new long[1];
   4454             pss[i] = Debug.getPss(pids[i], tmpUss);
   4455             if (proc != null) {
   4456                 synchronized (this) {
   4457                     if (proc.thread != null && proc.setAdj == oomAdj) {
   4458                         // Record this for posterity if the process has been stable.
   4459                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
   4460                     }
   4461                 }
   4462             }
   4463         }
   4464         return pss;
   4465     }
   4466 
   4467     @Override
   4468     public void killApplicationProcess(String processName, int uid) {
   4469         if (processName == null) {
   4470             return;
   4471         }
   4472 
   4473         int callerUid = Binder.getCallingUid();
   4474         // Only the system server can kill an application
   4475         if (callerUid == Process.SYSTEM_UID) {
   4476             synchronized (this) {
   4477                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
   4478                 if (app != null && app.thread != null) {
   4479                     try {
   4480                         app.thread.scheduleSuicide();
   4481                     } catch (RemoteException e) {
   4482                         // If the other end already died, then our work here is done.
   4483                     }
   4484                 } else {
   4485                     Slog.w(TAG, "Process/uid not found attempting kill of "
   4486                             + processName + " / " + uid);
   4487                 }
   4488             }
   4489         } else {
   4490             throw new SecurityException(callerUid + " cannot kill app process: " +
   4491                     processName);
   4492         }
   4493     }
   4494 
   4495     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
   4496         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
   4497                 false, true, false, false, UserHandle.getUserId(uid), reason);
   4498         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
   4499                 Uri.fromParts("package", packageName, null));
   4500         if (!mProcessesReady) {
   4501             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4502                     | Intent.FLAG_RECEIVER_FOREGROUND);
   4503         }
   4504         intent.putExtra(Intent.EXTRA_UID, uid);
   4505         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
   4506         broadcastIntentLocked(null, null, intent,
   4507                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   4508                 false, false,
   4509                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
   4510     }
   4511 
   4512     private void forceStopUserLocked(int userId, String reason) {
   4513         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
   4514         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
   4515         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   4516                 | Intent.FLAG_RECEIVER_FOREGROUND);
   4517         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   4518         broadcastIntentLocked(null, null, intent,
   4519                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   4520                 false, false,
   4521                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   4522     }
   4523 
   4524     private final boolean killPackageProcessesLocked(String packageName, int appId,
   4525             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
   4526             boolean doit, boolean evenPersistent, String reason) {
   4527         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   4528 
   4529         // Remove all processes this package may have touched: all with the
   4530         // same UID (except for the system or root user), and all whose name
   4531         // matches the package name.
   4532         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
   4533         final int NP = mProcessNames.getMap().size();
   4534         for (int ip=0; ip<NP; ip++) {
   4535             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   4536             final int NA = apps.size();
   4537             for (int ia=0; ia<NA; ia++) {
   4538                 ProcessRecord app = apps.valueAt(ia);
   4539                 if (app.persistent && !evenPersistent) {
   4540                     // we don't kill persistent processes
   4541                     continue;
   4542                 }
   4543                 if (app.removed) {
   4544                     if (doit) {
   4545                         procs.add(app);
   4546                     }
   4547                     continue;
   4548                 }
   4549 
   4550                 // Skip process if it doesn't meet our oom adj requirement.
   4551                 if (app.setAdj < minOomAdj) {
   4552                     continue;
   4553                 }
   4554 
   4555                 // If no package is specified, we call all processes under the
   4556                 // give user id.
   4557                 if (packageName == null) {
   4558                     if (app.userId != userId) {
   4559                         continue;
   4560                     }
   4561                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
   4562                         continue;
   4563                     }
   4564                 // Package has been specified, we want to hit all processes
   4565                 // that match it.  We need to qualify this by the processes
   4566                 // that are running under the specified app and user ID.
   4567                 } else {
   4568                     if (UserHandle.getAppId(app.uid) != appId) {
   4569                         continue;
   4570                     }
   4571                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
   4572                         continue;
   4573                     }
   4574                     if (!app.pkgList.containsKey(packageName)) {
   4575                         continue;
   4576                     }
   4577                 }
   4578 
   4579                 // Process has passed all conditions, kill it!
   4580                 if (!doit) {
   4581                     return true;
   4582                 }
   4583                 app.removed = true;
   4584                 procs.add(app);
   4585             }
   4586         }
   4587 
   4588         int N = procs.size();
   4589         for (int i=0; i<N; i++) {
   4590             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
   4591         }
   4592         updateOomAdjLocked();
   4593         return N > 0;
   4594     }
   4595 
   4596     private final boolean forceStopPackageLocked(String name, int appId,
   4597             boolean callerWillRestart, boolean purgeCache, boolean doit,
   4598             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
   4599         int i;
   4600         int N;
   4601 
   4602         if (userId == UserHandle.USER_ALL && name == null) {
   4603             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
   4604         }
   4605 
   4606         if (appId < 0 && name != null) {
   4607             try {
   4608                 appId = UserHandle.getAppId(
   4609                         AppGlobals.getPackageManager().getPackageUid(name, 0));
   4610             } catch (RemoteException e) {
   4611             }
   4612         }
   4613 
   4614         if (doit) {
   4615             if (name != null) {
   4616                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
   4617                         + " user=" + userId + ": " + reason);
   4618             } else {
   4619                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
   4620             }
   4621 
   4622             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   4623             for (int ip=pmap.size()-1; ip>=0; ip--) {
   4624                 SparseArray<Long> ba = pmap.valueAt(ip);
   4625                 for (i=ba.size()-1; i>=0; i--) {
   4626                     boolean remove = false;
   4627                     final int entUid = ba.keyAt(i);
   4628                     if (name != null) {
   4629                         if (userId == UserHandle.USER_ALL) {
   4630                             if (UserHandle.getAppId(entUid) == appId) {
   4631                                 remove = true;
   4632                             }
   4633                         } else {
   4634                             if (entUid == UserHandle.getUid(userId, appId)) {
   4635                                 remove = true;
   4636                             }
   4637                         }
   4638                     } else if (UserHandle.getUserId(entUid) == userId) {
   4639                         remove = true;
   4640                     }
   4641                     if (remove) {
   4642                         ba.removeAt(i);
   4643                     }
   4644                 }
   4645                 if (ba.size() == 0) {
   4646                     pmap.removeAt(ip);
   4647                 }
   4648             }
   4649         }
   4650 
   4651         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
   4652                 -100, callerWillRestart, true, doit, evenPersistent,
   4653                 name == null ? ("stop user " + userId) : ("stop " + name));
   4654 
   4655         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
   4656             if (!doit) {
   4657                 return true;
   4658             }
   4659             didSomething = true;
   4660         }
   4661 
   4662         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
   4663             if (!doit) {
   4664                 return true;
   4665             }
   4666             didSomething = true;
   4667         }
   4668 
   4669         if (name == null) {
   4670             // Remove all sticky broadcasts from this user.
   4671             mStickyBroadcasts.remove(userId);
   4672         }
   4673 
   4674         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
   4675         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
   4676                 userId, providers)) {
   4677             if (!doit) {
   4678                 return true;
   4679             }
   4680             didSomething = true;
   4681         }
   4682         N = providers.size();
   4683         for (i=0; i<N; i++) {
   4684             removeDyingProviderLocked(null, providers.get(i), true);
   4685         }
   4686 
   4687         // Remove transient permissions granted from/to this package/user
   4688         removeUriPermissionsForPackageLocked(name, userId, false);
   4689 
   4690         if (name == null || uninstalling) {
   4691             // Remove pending intents.  For now we only do this when force
   4692             // stopping users, because we have some problems when doing this
   4693             // for packages -- app widgets are not currently cleaned up for
   4694             // such packages, so they can be left with bad pending intents.
   4695             if (mIntentSenderRecords.size() > 0) {
   4696                 Iterator<WeakReference<PendingIntentRecord>> it
   4697                         = mIntentSenderRecords.values().iterator();
   4698                 while (it.hasNext()) {
   4699                     WeakReference<PendingIntentRecord> wpir = it.next();
   4700                     if (wpir == null) {
   4701                         it.remove();
   4702                         continue;
   4703                     }
   4704                     PendingIntentRecord pir = wpir.get();
   4705                     if (pir == null) {
   4706                         it.remove();
   4707                         continue;
   4708                     }
   4709                     if (name == null) {
   4710                         // Stopping user, remove all objects for the user.
   4711                         if (pir.key.userId != userId) {
   4712                             // Not the same user, skip it.
   4713                             continue;
   4714                         }
   4715                     } else {
   4716                         if (UserHandle.getAppId(pir.uid) != appId) {
   4717                             // Different app id, skip it.
   4718                             continue;
   4719                         }
   4720                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
   4721                             // Different user, skip it.
   4722                             continue;
   4723                         }
   4724                         if (!pir.key.packageName.equals(name)) {
   4725                             // Different package, skip it.
   4726                             continue;
   4727                         }
   4728                     }
   4729                     if (!doit) {
   4730                         return true;
   4731                     }
   4732                     didSomething = true;
   4733                     it.remove();
   4734                     pir.canceled = true;
   4735                     if (pir.key.activity != null) {
   4736                         pir.key.activity.pendingResults.remove(pir.ref);
   4737                     }
   4738                 }
   4739             }
   4740         }
   4741 
   4742         if (doit) {
   4743             if (purgeCache && name != null) {
   4744                 AttributeCache ac = AttributeCache.instance();
   4745                 if (ac != null) {
   4746                     ac.removePackage(name);
   4747                 }
   4748             }
   4749             if (mBooted) {
   4750                 mStackSupervisor.resumeTopActivitiesLocked();
   4751                 mStackSupervisor.scheduleIdleLocked();
   4752             }
   4753         }
   4754 
   4755         return didSomething;
   4756     }
   4757 
   4758     private final boolean removeProcessLocked(ProcessRecord app,
   4759             boolean callerWillRestart, boolean allowRestart, String reason) {
   4760         final String name = app.processName;
   4761         final int uid = app.uid;
   4762         if (DEBUG_PROCESSES) Slog.d(
   4763             TAG, "Force removing proc " + app.toShortString() + " (" + name
   4764             + "/" + uid + ")");
   4765 
   4766         mProcessNames.remove(name, uid);
   4767         mIsolatedProcesses.remove(app.uid);
   4768         if (mHeavyWeightProcess == app) {
   4769             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4770                     mHeavyWeightProcess.userId, 0));
   4771             mHeavyWeightProcess = null;
   4772         }
   4773         boolean needRestart = false;
   4774         if (app.pid > 0 && app.pid != MY_PID) {
   4775             int pid = app.pid;
   4776             synchronized (mPidsSelfLocked) {
   4777                 mPidsSelfLocked.remove(pid);
   4778                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4779             }
   4780             killUnneededProcessLocked(app, reason);
   4781             handleAppDiedLocked(app, true, allowRestart);
   4782             removeLruProcessLocked(app);
   4783 
   4784             if (app.persistent && !app.isolated) {
   4785                 if (!callerWillRestart) {
   4786                     addAppLocked(app.info, false);
   4787                 } else {
   4788                     needRestart = true;
   4789                 }
   4790             }
   4791         } else {
   4792             mRemovedProcesses.add(app);
   4793         }
   4794 
   4795         return needRestart;
   4796     }
   4797 
   4798     private final void processStartTimedOutLocked(ProcessRecord app) {
   4799         final int pid = app.pid;
   4800         boolean gone = false;
   4801         synchronized (mPidsSelfLocked) {
   4802             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
   4803             if (knownApp != null && knownApp.thread == null) {
   4804                 mPidsSelfLocked.remove(pid);
   4805                 gone = true;
   4806             }
   4807         }
   4808 
   4809         if (gone) {
   4810             Slog.w(TAG, "Process " + app + " failed to attach");
   4811             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
   4812                     pid, app.uid, app.processName);
   4813             mProcessNames.remove(app.processName, app.uid);
   4814             mIsolatedProcesses.remove(app.uid);
   4815             if (mHeavyWeightProcess == app) {
   4816                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   4817                         mHeavyWeightProcess.userId, 0));
   4818                 mHeavyWeightProcess = null;
   4819             }
   4820             // Take care of any launching providers waiting for this process.
   4821             checkAppInLaunchingProvidersLocked(app, true);
   4822             // Take care of any services that are waiting for the process.
   4823             mServices.processStartTimedOutLocked(app);
   4824             killUnneededProcessLocked(app, "start timeout");
   4825             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
   4826                 Slog.w(TAG, "Unattached app died before backup, skipping");
   4827                 try {
   4828                     IBackupManager bm = IBackupManager.Stub.asInterface(
   4829                             ServiceManager.getService(Context.BACKUP_SERVICE));
   4830                     bm.agentDisconnected(app.info.packageName);
   4831                 } catch (RemoteException e) {
   4832                     // Can't happen; the backup manager is local
   4833                 }
   4834             }
   4835             if (isPendingBroadcastProcessLocked(pid)) {
   4836                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   4837                 skipPendingBroadcastLocked(pid);
   4838             }
   4839         } else {
   4840             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
   4841         }
   4842     }
   4843 
   4844     private final boolean attachApplicationLocked(IApplicationThread thread,
   4845             int pid) {
   4846 
   4847         // Find the application record that is being attached...  either via
   4848         // the pid if we are running in multiple processes, or just pull the
   4849         // next app record if we are emulating process with anonymous threads.
   4850         ProcessRecord app;
   4851         if (pid != MY_PID && pid >= 0) {
   4852             synchronized (mPidsSelfLocked) {
   4853                 app = mPidsSelfLocked.get(pid);
   4854             }
   4855         } else {
   4856             app = null;
   4857         }
   4858 
   4859         if (app == null) {
   4860             Slog.w(TAG, "No pending application record for pid " + pid
   4861                     + " (IApplicationThread " + thread + "); dropping process");
   4862             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
   4863             if (pid > 0 && pid != MY_PID) {
   4864                 Process.killProcessQuiet(pid);
   4865             } else {
   4866                 try {
   4867                     thread.scheduleExit();
   4868                 } catch (Exception e) {
   4869                     // Ignore exceptions.
   4870                 }
   4871             }
   4872             return false;
   4873         }
   4874 
   4875         // If this application record is still attached to a previous
   4876         // process, clean it up now.
   4877         if (app.thread != null) {
   4878             handleAppDiedLocked(app, true, true);
   4879         }
   4880 
   4881         // Tell the process all about itself.
   4882 
   4883         if (localLOGV) Slog.v(
   4884                 TAG, "Binding process pid " + pid + " to record " + app);
   4885 
   4886         final String processName = app.processName;
   4887         try {
   4888             AppDeathRecipient adr = new AppDeathRecipient(
   4889                     app, pid, thread);
   4890             thread.asBinder().linkToDeath(adr, 0);
   4891             app.deathRecipient = adr;
   4892         } catch (RemoteException e) {
   4893             app.resetPackageList(mProcessStats);
   4894             startProcessLocked(app, "link fail", processName);
   4895             return false;
   4896         }
   4897 
   4898         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
   4899 
   4900         app.makeActive(thread, mProcessStats);
   4901         app.curAdj = app.setAdj = -100;
   4902         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
   4903         app.forcingToForeground = null;
   4904         app.foregroundServices = false;
   4905         app.hasShownUi = false;
   4906         app.debugging = false;
   4907         app.cached = false;
   4908 
   4909         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   4910 
   4911         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
   4912         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
   4913 
   4914         if (!normalMode) {
   4915             Slog.i(TAG, "Launching preboot mode app: " + app);
   4916         }
   4917 
   4918         if (localLOGV) Slog.v(
   4919             TAG, "New app record " + app
   4920             + " thread=" + thread.asBinder() + " pid=" + pid);
   4921         try {
   4922             int testMode = IApplicationThread.DEBUG_OFF;
   4923             if (mDebugApp != null && mDebugApp.equals(processName)) {
   4924                 testMode = mWaitForDebugger
   4925                     ? IApplicationThread.DEBUG_WAIT
   4926                     : IApplicationThread.DEBUG_ON;
   4927                 app.debugging = true;
   4928                 if (mDebugTransient) {
   4929                     mDebugApp = mOrigDebugApp;
   4930                     mWaitForDebugger = mOrigWaitForDebugger;
   4931                 }
   4932             }
   4933             String profileFile = app.instrumentationProfileFile;
   4934             ParcelFileDescriptor profileFd = null;
   4935             boolean profileAutoStop = false;
   4936             if (mProfileApp != null && mProfileApp.equals(processName)) {
   4937                 mProfileProc = app;
   4938                 profileFile = mProfileFile;
   4939                 profileFd = mProfileFd;
   4940                 profileAutoStop = mAutoStopProfiler;
   4941             }
   4942             boolean enableOpenGlTrace = false;
   4943             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
   4944                 enableOpenGlTrace = true;
   4945                 mOpenGlTraceApp = null;
   4946             }
   4947 
   4948             // If the app is being launched for restore or full backup, set it up specially
   4949             boolean isRestrictedBackupMode = false;
   4950             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
   4951                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
   4952                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
   4953                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
   4954             }
   4955 
   4956             ensurePackageDexOpt(app.instrumentationInfo != null
   4957                     ? app.instrumentationInfo.packageName
   4958                     : app.info.packageName);
   4959             if (app.instrumentationClass != null) {
   4960                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
   4961             }
   4962             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
   4963                     + processName + " with config " + mConfiguration);
   4964             ApplicationInfo appInfo = app.instrumentationInfo != null
   4965                     ? app.instrumentationInfo : app.info;
   4966             app.compat = compatibilityInfoForPackageLocked(appInfo);
   4967             if (profileFd != null) {
   4968                 profileFd = profileFd.dup();
   4969             }
   4970             thread.bindApplication(processName, appInfo, providers,
   4971                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
   4972                     app.instrumentationArguments, app.instrumentationWatcher,
   4973                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
   4974                     isRestrictedBackupMode || !normalMode, app.persistent,
   4975                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
   4976                     mCoreSettingsObserver.getCoreSettingsLocked());
   4977             updateLruProcessLocked(app, false, null);
   4978             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   4979         } catch (Exception e) {
   4980             // todo: Yikes!  What should we do?  For now we will try to
   4981             // start another process, but that could easily get us in
   4982             // an infinite loop of restarting processes...
   4983             Slog.w(TAG, "Exception thrown during bind!", e);
   4984 
   4985             app.resetPackageList(mProcessStats);
   4986             app.unlinkDeathRecipient();
   4987             startProcessLocked(app, "bind fail", processName);
   4988             return false;
   4989         }
   4990 
   4991         // Remove this record from the list of starting applications.
   4992         mPersistentStartingProcesses.remove(app);
   4993         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
   4994                 "Attach application locked removing on hold: " + app);
   4995         mProcessesOnHold.remove(app);
   4996 
   4997         boolean badApp = false;
   4998         boolean didSomething = false;
   4999 
   5000         // See if the top visible activity is waiting to run in this process...
   5001         if (normalMode) {
   5002             try {
   5003                 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
   5004                     didSomething = true;
   5005                 }
   5006             } catch (Exception e) {
   5007                 badApp = true;
   5008             }
   5009         }
   5010 
   5011         // Find any services that should be running in this process...
   5012         if (!badApp) {
   5013             try {
   5014                 didSomething |= mServices.attachApplicationLocked(app, processName);
   5015             } catch (Exception e) {
   5016                 badApp = true;
   5017             }
   5018         }
   5019 
   5020         // Check if a next-broadcast receiver is in this process...
   5021         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
   5022             try {
   5023                 didSomething |= sendPendingBroadcastsLocked(app);
   5024             } catch (Exception e) {
   5025                 // If the app died trying to launch the receiver we declare it 'bad'
   5026                 badApp = true;
   5027             }
   5028         }
   5029 
   5030         // Check whether the next backup agent is in this process...
   5031         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
   5032             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
   5033             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
   5034             try {
   5035                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
   5036                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
   5037                         mBackupTarget.backupMode);
   5038             } catch (Exception e) {
   5039                 Slog.w(TAG, "Exception scheduling backup agent creation: ");
   5040                 e.printStackTrace();
   5041             }
   5042         }
   5043 
   5044         if (badApp) {
   5045             // todo: Also need to kill application to deal with all
   5046             // kinds of exceptions.
   5047             handleAppDiedLocked(app, false, true);
   5048             return false;
   5049         }
   5050 
   5051         if (!didSomething) {
   5052             updateOomAdjLocked();
   5053         }
   5054 
   5055         return true;
   5056     }
   5057 
   5058     @Override
   5059     public final void attachApplication(IApplicationThread thread) {
   5060         synchronized (this) {
   5061             int callingPid = Binder.getCallingPid();
   5062             final long origId = Binder.clearCallingIdentity();
   5063             attachApplicationLocked(thread, callingPid);
   5064             Binder.restoreCallingIdentity(origId);
   5065         }
   5066     }
   5067 
   5068     @Override
   5069     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
   5070         final long origId = Binder.clearCallingIdentity();
   5071         synchronized (this) {
   5072             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5073             if (stack != null) {
   5074                 ActivityRecord r =
   5075                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
   5076                 if (stopProfiling) {
   5077                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
   5078                         try {
   5079                             mProfileFd.close();
   5080                         } catch (IOException e) {
   5081                         }
   5082                         clearProfilerLocked();
   5083                     }
   5084                 }
   5085             }
   5086         }
   5087         Binder.restoreCallingIdentity(origId);
   5088     }
   5089 
   5090     void enableScreenAfterBoot() {
   5091         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
   5092                 SystemClock.uptimeMillis());
   5093         mWindowManager.enableScreenAfterBoot();
   5094 
   5095         synchronized (this) {
   5096             updateEventDispatchingLocked();
   5097         }
   5098     }
   5099 
   5100     @Override
   5101     public void showBootMessage(final CharSequence msg, final boolean always) {
   5102         enforceNotIsolatedCaller("showBootMessage");
   5103         mWindowManager.showBootMessage(msg, always);
   5104     }
   5105 
   5106     @Override
   5107     public void dismissKeyguardOnNextActivity() {
   5108         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
   5109         final long token = Binder.clearCallingIdentity();
   5110         try {
   5111             synchronized (this) {
   5112                 if (DEBUG_LOCKSCREEN) logLockScreen("");
   5113                 if (mLockScreenShown) {
   5114                     mLockScreenShown = false;
   5115                     comeOutOfSleepIfNeededLocked();
   5116                 }
   5117                 mStackSupervisor.setDismissKeyguard(true);
   5118             }
   5119         } finally {
   5120             Binder.restoreCallingIdentity(token);
   5121         }
   5122     }
   5123 
   5124     final void finishBooting() {
   5125         IntentFilter pkgFilter = new IntentFilter();
   5126         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
   5127         pkgFilter.addDataScheme("package");
   5128         mContext.registerReceiver(new BroadcastReceiver() {
   5129             @Override
   5130             public void onReceive(Context context, Intent intent) {
   5131                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
   5132                 if (pkgs != null) {
   5133                     for (String pkg : pkgs) {
   5134                         synchronized (ActivityManagerService.this) {
   5135                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
   5136                                     "finished booting")) {
   5137                                 setResultCode(Activity.RESULT_OK);
   5138                                 return;
   5139                             }
   5140                         }
   5141                     }
   5142                 }
   5143             }
   5144         }, pkgFilter);
   5145 
   5146         synchronized (this) {
   5147             // Ensure that any processes we had put on hold are now started
   5148             // up.
   5149             final int NP = mProcessesOnHold.size();
   5150             if (NP > 0) {
   5151                 ArrayList<ProcessRecord> procs =
   5152                     new ArrayList<ProcessRecord>(mProcessesOnHold);
   5153                 for (int ip=0; ip<NP; ip++) {
   5154                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
   5155                             + procs.get(ip));
   5156                     startProcessLocked(procs.get(ip), "on-hold", null);
   5157                 }
   5158             }
   5159 
   5160             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   5161                 // Start looking for apps that are abusing wake locks.
   5162                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   5163                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   5164                 // Tell anyone interested that we are done booting!
   5165                 SystemProperties.set("sys.boot_completed", "1");
   5166                 SystemProperties.set("dev.bootcomplete", "1");
   5167                 for (int i=0; i<mStartedUsers.size(); i++) {
   5168                     UserStartedState uss = mStartedUsers.valueAt(i);
   5169                     if (uss.mState == UserStartedState.STATE_BOOTING) {
   5170                         uss.mState = UserStartedState.STATE_RUNNING;
   5171                         final int userId = mStartedUsers.keyAt(i);
   5172                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   5173                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   5174                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   5175                         broadcastIntentLocked(null, null, intent, null,
   5176                                 new IIntentReceiver.Stub() {
   5177                                     @Override
   5178                                     public void performReceive(Intent intent, int resultCode,
   5179                                             String data, Bundle extras, boolean ordered,
   5180                                             boolean sticky, int sendingUser) {
   5181                                         synchronized (ActivityManagerService.this) {
   5182                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
   5183                                                     true, false);
   5184                                         }
   5185                                     }
   5186                                 },
   5187                                 0, null, null,
   5188                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
   5189                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
   5190                                 userId);
   5191                     }
   5192                 }
   5193             }
   5194         }
   5195     }
   5196 
   5197     final void ensureBootCompleted() {
   5198         boolean booting;
   5199         boolean enableScreen;
   5200         synchronized (this) {
   5201             booting = mBooting;
   5202             mBooting = false;
   5203             enableScreen = !mBooted;
   5204             mBooted = true;
   5205         }
   5206 
   5207         if (booting) {
   5208             finishBooting();
   5209         }
   5210 
   5211         if (enableScreen) {
   5212             enableScreenAfterBoot();
   5213         }
   5214     }
   5215 
   5216     @Override
   5217     public final void activityResumed(IBinder token) {
   5218         final long origId = Binder.clearCallingIdentity();
   5219         synchronized(this) {
   5220             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5221             if (stack != null) {
   5222                 ActivityRecord.activityResumedLocked(token);
   5223             }
   5224         }
   5225         Binder.restoreCallingIdentity(origId);
   5226     }
   5227 
   5228     @Override
   5229     public final void activityPaused(IBinder token) {
   5230         final long origId = Binder.clearCallingIdentity();
   5231         synchronized(this) {
   5232             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5233             if (stack != null) {
   5234                 stack.activityPausedLocked(token, false);
   5235             }
   5236         }
   5237         Binder.restoreCallingIdentity(origId);
   5238     }
   5239 
   5240     @Override
   5241     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
   5242             CharSequence description) {
   5243         if (localLOGV) Slog.v(
   5244             TAG, "Activity stopped: token=" + token);
   5245 
   5246         // Refuse possible leaked file descriptors
   5247         if (icicle != null && icicle.hasFileDescriptors()) {
   5248             throw new IllegalArgumentException("File descriptors passed in Bundle");
   5249         }
   5250 
   5251         ActivityRecord r = null;
   5252 
   5253         final long origId = Binder.clearCallingIdentity();
   5254 
   5255         synchronized (this) {
   5256             r = ActivityRecord.isInStackLocked(token);
   5257             if (r != null) {
   5258                 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
   5259             }
   5260         }
   5261 
   5262         if (r != null) {
   5263             sendPendingThumbnail(r, null, null, null, false);
   5264         }
   5265 
   5266         trimApplications();
   5267 
   5268         Binder.restoreCallingIdentity(origId);
   5269     }
   5270 
   5271     @Override
   5272     public final void activityDestroyed(IBinder token) {
   5273         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
   5274         synchronized (this) {
   5275             ActivityStack stack = ActivityRecord.getStackLocked(token);
   5276             if (stack != null) {
   5277                 stack.activityDestroyedLocked(token);
   5278             }
   5279         }
   5280     }
   5281 
   5282     @Override
   5283     public String getCallingPackage(IBinder token) {
   5284         synchronized (this) {
   5285             ActivityRecord r = getCallingRecordLocked(token);
   5286             return r != null ? r.info.packageName : null;
   5287         }
   5288     }
   5289 
   5290     @Override
   5291     public ComponentName getCallingActivity(IBinder token) {
   5292         synchronized (this) {
   5293             ActivityRecord r = getCallingRecordLocked(token);
   5294             return r != null ? r.intent.getComponent() : null;
   5295         }
   5296     }
   5297 
   5298     private ActivityRecord getCallingRecordLocked(IBinder token) {
   5299         ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5300         if (r == null) {
   5301             return null;
   5302         }
   5303         return r.resultTo;
   5304     }
   5305 
   5306     @Override
   5307     public ComponentName getActivityClassForToken(IBinder token) {
   5308         synchronized(this) {
   5309             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5310             if (r == null) {
   5311                 return null;
   5312             }
   5313             return r.intent.getComponent();
   5314         }
   5315     }
   5316 
   5317     @Override
   5318     public String getPackageForToken(IBinder token) {
   5319         synchronized(this) {
   5320             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   5321             if (r == null) {
   5322                 return null;
   5323             }
   5324             return r.packageName;
   5325         }
   5326     }
   5327 
   5328     @Override
   5329     public IIntentSender getIntentSender(int type,
   5330             String packageName, IBinder token, String resultWho,
   5331             int requestCode, Intent[] intents, String[] resolvedTypes,
   5332             int flags, Bundle options, int userId) {
   5333         enforceNotIsolatedCaller("getIntentSender");
   5334         // Refuse possible leaked file descriptors
   5335         if (intents != null) {
   5336             if (intents.length < 1) {
   5337                 throw new IllegalArgumentException("Intents array length must be >= 1");
   5338             }
   5339             for (int i=0; i<intents.length; i++) {
   5340                 Intent intent = intents[i];
   5341                 if (intent != null) {
   5342                     if (intent.hasFileDescriptors()) {
   5343                         throw new IllegalArgumentException("File descriptors passed in Intent");
   5344                     }
   5345                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
   5346                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   5347                         throw new IllegalArgumentException(
   5348                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   5349                     }
   5350                     intents[i] = new Intent(intent);
   5351                 }
   5352             }
   5353             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
   5354                 throw new IllegalArgumentException(
   5355                         "Intent array length does not match resolvedTypes length");
   5356             }
   5357         }
   5358         if (options != null) {
   5359             if (options.hasFileDescriptors()) {
   5360                 throw new IllegalArgumentException("File descriptors passed in options");
   5361             }
   5362         }
   5363 
   5364         synchronized(this) {
   5365             int callingUid = Binder.getCallingUid();
   5366             int origUserId = userId;
   5367             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
   5368                     type == ActivityManager.INTENT_SENDER_BROADCAST, false,
   5369                     "getIntentSender", null);
   5370             if (origUserId == UserHandle.USER_CURRENT) {
   5371                 // We don't want to evaluate this until the pending intent is
   5372                 // actually executed.  However, we do want to always do the
   5373                 // security checking for it above.
   5374                 userId = UserHandle.USER_CURRENT;
   5375             }
   5376             try {
   5377                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   5378                     int uid = AppGlobals.getPackageManager()
   5379                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
   5380                     if (!UserHandle.isSameApp(callingUid, uid)) {
   5381                         String msg = "Permission Denial: getIntentSender() from pid="
   5382                             + Binder.getCallingPid()
   5383                             + ", uid=" + Binder.getCallingUid()
   5384                             + ", (need uid=" + uid + ")"
   5385                             + " is not allowed to send as package " + packageName;
   5386                         Slog.w(TAG, msg);
   5387                         throw new SecurityException(msg);
   5388                     }
   5389                 }
   5390 
   5391                 return getIntentSenderLocked(type, packageName, callingUid, userId,
   5392                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
   5393 
   5394             } catch (RemoteException e) {
   5395                 throw new SecurityException(e);
   5396             }
   5397         }
   5398     }
   5399 
   5400     IIntentSender getIntentSenderLocked(int type, String packageName,
   5401             int callingUid, int userId, IBinder token, String resultWho,
   5402             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
   5403             Bundle options) {
   5404         if (DEBUG_MU)
   5405             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
   5406         ActivityRecord activity = null;
   5407         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   5408             activity = ActivityRecord.isInStackLocked(token);
   5409             if (activity == null) {
   5410                 return null;
   5411             }
   5412             if (activity.finishing) {
   5413                 return null;
   5414             }
   5415         }
   5416 
   5417         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
   5418         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
   5419         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
   5420         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
   5421                 |PendingIntent.FLAG_UPDATE_CURRENT);
   5422 
   5423         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
   5424                 type, packageName, activity, resultWho,
   5425                 requestCode, intents, resolvedTypes, flags, options, userId);
   5426         WeakReference<PendingIntentRecord> ref;
   5427         ref = mIntentSenderRecords.get(key);
   5428         PendingIntentRecord rec = ref != null ? ref.get() : null;
   5429         if (rec != null) {
   5430             if (!cancelCurrent) {
   5431                 if (updateCurrent) {
   5432                     if (rec.key.requestIntent != null) {
   5433                         rec.key.requestIntent.replaceExtras(intents != null ?
   5434                                 intents[intents.length - 1] : null);
   5435                     }
   5436                     if (intents != null) {
   5437                         intents[intents.length-1] = rec.key.requestIntent;
   5438                         rec.key.allIntents = intents;
   5439                         rec.key.allResolvedTypes = resolvedTypes;
   5440                     } else {
   5441                         rec.key.allIntents = null;
   5442                         rec.key.allResolvedTypes = null;
   5443                     }
   5444                 }
   5445                 return rec;
   5446             }
   5447             rec.canceled = true;
   5448             mIntentSenderRecords.remove(key);
   5449         }
   5450         if (noCreate) {
   5451             return rec;
   5452         }
   5453         rec = new PendingIntentRecord(this, key, callingUid);
   5454         mIntentSenderRecords.put(key, rec.ref);
   5455         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
   5456             if (activity.pendingResults == null) {
   5457                 activity.pendingResults
   5458                         = new HashSet<WeakReference<PendingIntentRecord>>();
   5459             }
   5460             activity.pendingResults.add(rec.ref);
   5461         }
   5462         return rec;
   5463     }
   5464 
   5465     @Override
   5466     public void cancelIntentSender(IIntentSender sender) {
   5467         if (!(sender instanceof PendingIntentRecord)) {
   5468             return;
   5469         }
   5470         synchronized(this) {
   5471             PendingIntentRecord rec = (PendingIntentRecord)sender;
   5472             try {
   5473                 int uid = AppGlobals.getPackageManager()
   5474                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
   5475                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
   5476                     String msg = "Permission Denial: cancelIntentSender() from pid="
   5477                         + Binder.getCallingPid()
   5478                         + ", uid=" + Binder.getCallingUid()
   5479                         + " is not allowed to cancel packges "
   5480                         + rec.key.packageName;
   5481                     Slog.w(TAG, msg);
   5482                     throw new SecurityException(msg);
   5483                 }
   5484             } catch (RemoteException e) {
   5485                 throw new SecurityException(e);
   5486             }
   5487             cancelIntentSenderLocked(rec, true);
   5488         }
   5489     }
   5490 
   5491     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
   5492         rec.canceled = true;
   5493         mIntentSenderRecords.remove(rec.key);
   5494         if (cleanActivity && rec.key.activity != null) {
   5495             rec.key.activity.pendingResults.remove(rec.ref);
   5496         }
   5497     }
   5498 
   5499     @Override
   5500     public String getPackageForIntentSender(IIntentSender pendingResult) {
   5501         if (!(pendingResult instanceof PendingIntentRecord)) {
   5502             return null;
   5503         }
   5504         try {
   5505             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5506             return res.key.packageName;
   5507         } catch (ClassCastException e) {
   5508         }
   5509         return null;
   5510     }
   5511 
   5512     @Override
   5513     public int getUidForIntentSender(IIntentSender sender) {
   5514         if (sender instanceof PendingIntentRecord) {
   5515             try {
   5516                 PendingIntentRecord res = (PendingIntentRecord)sender;
   5517                 return res.uid;
   5518             } catch (ClassCastException e) {
   5519             }
   5520         }
   5521         return -1;
   5522     }
   5523 
   5524     @Override
   5525     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
   5526         if (!(pendingResult instanceof PendingIntentRecord)) {
   5527             return false;
   5528         }
   5529         try {
   5530             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5531             if (res.key.allIntents == null) {
   5532                 return false;
   5533             }
   5534             for (int i=0; i<res.key.allIntents.length; i++) {
   5535                 Intent intent = res.key.allIntents[i];
   5536                 if (intent.getPackage() != null && intent.getComponent() != null) {
   5537                     return false;
   5538                 }
   5539             }
   5540             return true;
   5541         } catch (ClassCastException e) {
   5542         }
   5543         return false;
   5544     }
   5545 
   5546     @Override
   5547     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
   5548         if (!(pendingResult instanceof PendingIntentRecord)) {
   5549             return false;
   5550         }
   5551         try {
   5552             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5553             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
   5554                 return true;
   5555             }
   5556             return false;
   5557         } catch (ClassCastException e) {
   5558         }
   5559         return false;
   5560     }
   5561 
   5562     @Override
   5563     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
   5564         if (!(pendingResult instanceof PendingIntentRecord)) {
   5565             return null;
   5566         }
   5567         try {
   5568             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
   5569             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
   5570         } catch (ClassCastException e) {
   5571         }
   5572         return null;
   5573     }
   5574 
   5575     @Override
   5576     public void setProcessLimit(int max) {
   5577         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   5578                 "setProcessLimit()");
   5579         synchronized (this) {
   5580             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
   5581             mProcessLimitOverride = max;
   5582         }
   5583         trimApplications();
   5584     }
   5585 
   5586     @Override
   5587     public int getProcessLimit() {
   5588         synchronized (this) {
   5589             return mProcessLimitOverride;
   5590         }
   5591     }
   5592 
   5593     void foregroundTokenDied(ForegroundToken token) {
   5594         synchronized (ActivityManagerService.this) {
   5595             synchronized (mPidsSelfLocked) {
   5596                 ForegroundToken cur
   5597                     = mForegroundProcesses.get(token.pid);
   5598                 if (cur != token) {
   5599                     return;
   5600                 }
   5601                 mForegroundProcesses.remove(token.pid);
   5602                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
   5603                 if (pr == null) {
   5604                     return;
   5605                 }
   5606                 pr.forcingToForeground = null;
   5607                 pr.foregroundServices = false;
   5608             }
   5609             updateOomAdjLocked();
   5610         }
   5611     }
   5612 
   5613     @Override
   5614     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
   5615         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
   5616                 "setProcessForeground()");
   5617         synchronized(this) {
   5618             boolean changed = false;
   5619 
   5620             synchronized (mPidsSelfLocked) {
   5621                 ProcessRecord pr = mPidsSelfLocked.get(pid);
   5622                 if (pr == null && isForeground) {
   5623                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
   5624                     return;
   5625                 }
   5626                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
   5627                 if (oldToken != null) {
   5628                     oldToken.token.unlinkToDeath(oldToken, 0);
   5629                     mForegroundProcesses.remove(pid);
   5630                     if (pr != null) {
   5631                         pr.forcingToForeground = null;
   5632                     }
   5633                     changed = true;
   5634                 }
   5635                 if (isForeground && token != null) {
   5636                     ForegroundToken newToken = new ForegroundToken() {
   5637                         @Override
   5638                         public void binderDied() {
   5639                             foregroundTokenDied(this);
   5640                         }
   5641                     };
   5642                     newToken.pid = pid;
   5643                     newToken.token = token;
   5644                     try {
   5645                         token.linkToDeath(newToken, 0);
   5646                         mForegroundProcesses.put(pid, newToken);
   5647                         pr.forcingToForeground = token;
   5648                         changed = true;
   5649                     } catch (RemoteException e) {
   5650                         // If the process died while doing this, we will later
   5651                         // do the cleanup with the process death link.
   5652                     }
   5653                 }
   5654             }
   5655 
   5656             if (changed) {
   5657                 updateOomAdjLocked();
   5658             }
   5659         }
   5660     }
   5661 
   5662     // =========================================================
   5663     // PERMISSIONS
   5664     // =========================================================
   5665 
   5666     static class PermissionController extends IPermissionController.Stub {
   5667         ActivityManagerService mActivityManagerService;
   5668         PermissionController(ActivityManagerService activityManagerService) {
   5669             mActivityManagerService = activityManagerService;
   5670         }
   5671 
   5672         @Override
   5673         public boolean checkPermission(String permission, int pid, int uid) {
   5674             return mActivityManagerService.checkPermission(permission, pid,
   5675                     uid) == PackageManager.PERMISSION_GRANTED;
   5676         }
   5677     }
   5678 
   5679     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
   5680         @Override
   5681         public int checkComponentPermission(String permission, int pid, int uid,
   5682                 int owningUid, boolean exported) {
   5683             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
   5684                     owningUid, exported);
   5685         }
   5686 
   5687         @Override
   5688         public Object getAMSLock() {
   5689             return ActivityManagerService.this;
   5690         }
   5691     }
   5692 
   5693     /**
   5694      * This can be called with or without the global lock held.
   5695      */
   5696     int checkComponentPermission(String permission, int pid, int uid,
   5697             int owningUid, boolean exported) {
   5698         // We might be performing an operation on behalf of an indirect binder
   5699         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
   5700         // client identity accordingly before proceeding.
   5701         Identity tlsIdentity = sCallerIdentity.get();
   5702         if (tlsIdentity != null) {
   5703             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
   5704                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
   5705             uid = tlsIdentity.uid;
   5706             pid = tlsIdentity.pid;
   5707         }
   5708 
   5709         if (pid == MY_PID) {
   5710             return PackageManager.PERMISSION_GRANTED;
   5711         }
   5712 
   5713         return ActivityManager.checkComponentPermission(permission, uid,
   5714                 owningUid, exported);
   5715     }
   5716 
   5717     /**
   5718      * As the only public entry point for permissions checking, this method
   5719      * can enforce the semantic that requesting a check on a null global
   5720      * permission is automatically denied.  (Internally a null permission
   5721      * string is used when calling {@link #checkComponentPermission} in cases
   5722      * when only uid-based security is needed.)
   5723      *
   5724      * This can be called with or without the global lock held.
   5725      */
   5726     @Override
   5727     public int checkPermission(String permission, int pid, int uid) {
   5728         if (permission == null) {
   5729             return PackageManager.PERMISSION_DENIED;
   5730         }
   5731         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
   5732     }
   5733 
   5734     /**
   5735      * Binder IPC calls go through the public entry point.
   5736      * This can be called with or without the global lock held.
   5737      */
   5738     int checkCallingPermission(String permission) {
   5739         return checkPermission(permission,
   5740                 Binder.getCallingPid(),
   5741                 UserHandle.getAppId(Binder.getCallingUid()));
   5742     }
   5743 
   5744     /**
   5745      * This can be called with or without the global lock held.
   5746      */
   5747     void enforceCallingPermission(String permission, String func) {
   5748         if (checkCallingPermission(permission)
   5749                 == PackageManager.PERMISSION_GRANTED) {
   5750             return;
   5751         }
   5752 
   5753         String msg = "Permission Denial: " + func + " from pid="
   5754                 + Binder.getCallingPid()
   5755                 + ", uid=" + Binder.getCallingUid()
   5756                 + " requires " + permission;
   5757         Slog.w(TAG, msg);
   5758         throw new SecurityException(msg);
   5759     }
   5760 
   5761     /**
   5762      * Determine if UID is holding permissions required to access {@link Uri} in
   5763      * the given {@link ProviderInfo}. Final permission checking is always done
   5764      * in {@link ContentProvider}.
   5765      */
   5766     private final boolean checkHoldingPermissionsLocked(
   5767             IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
   5768         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5769                 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
   5770 
   5771         if (pi.applicationInfo.uid == uid) {
   5772             return true;
   5773         } else if (!pi.exported) {
   5774             return false;
   5775         }
   5776 
   5777         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
   5778         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
   5779         try {
   5780             // check if target holds top-level <provider> permissions
   5781             if (!readMet && pi.readPermission != null
   5782                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
   5783                 readMet = true;
   5784             }
   5785             if (!writeMet && pi.writePermission != null
   5786                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
   5787                 writeMet = true;
   5788             }
   5789 
   5790             // track if unprotected read/write is allowed; any denied
   5791             // <path-permission> below removes this ability
   5792             boolean allowDefaultRead = pi.readPermission == null;
   5793             boolean allowDefaultWrite = pi.writePermission == null;
   5794 
   5795             // check if target holds any <path-permission> that match uri
   5796             final PathPermission[] pps = pi.pathPermissions;
   5797             if (pps != null) {
   5798                 final String path = uri.getPath();
   5799                 int i = pps.length;
   5800                 while (i > 0 && (!readMet || !writeMet)) {
   5801                     i--;
   5802                     PathPermission pp = pps[i];
   5803                     if (pp.match(path)) {
   5804                         if (!readMet) {
   5805                             final String pprperm = pp.getReadPermission();
   5806                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
   5807                                     + pprperm + " for " + pp.getPath()
   5808                                     + ": match=" + pp.match(path)
   5809                                     + " check=" + pm.checkUidPermission(pprperm, uid));
   5810                             if (pprperm != null) {
   5811                                 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
   5812                                     readMet = true;
   5813                                 } else {
   5814                                     allowDefaultRead = false;
   5815                                 }
   5816                             }
   5817                         }
   5818                         if (!writeMet) {
   5819                             final String ppwperm = pp.getWritePermission();
   5820                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
   5821                                     + ppwperm + " for " + pp.getPath()
   5822                                     + ": match=" + pp.match(path)
   5823                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
   5824                             if (ppwperm != null) {
   5825                                 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
   5826                                     writeMet = true;
   5827                                 } else {
   5828                                     allowDefaultWrite = false;
   5829                                 }
   5830                             }
   5831                         }
   5832                     }
   5833                 }
   5834             }
   5835 
   5836             // grant unprotected <provider> read/write, if not blocked by
   5837             // <path-permission> above
   5838             if (allowDefaultRead) readMet = true;
   5839             if (allowDefaultWrite) writeMet = true;
   5840 
   5841         } catch (RemoteException e) {
   5842             return false;
   5843         }
   5844 
   5845         return readMet && writeMet;
   5846     }
   5847 
   5848     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
   5849         ProviderInfo pi = null;
   5850         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
   5851         if (cpr != null) {
   5852             pi = cpr.info;
   5853         } else {
   5854             try {
   5855                 pi = AppGlobals.getPackageManager().resolveContentProvider(
   5856                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
   5857             } catch (RemoteException ex) {
   5858             }
   5859         }
   5860         return pi;
   5861     }
   5862 
   5863     private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
   5864         ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   5865         if (targetUris != null) {
   5866             return targetUris.get(uri);
   5867         } else {
   5868             return null;
   5869         }
   5870     }
   5871 
   5872     private UriPermission findOrCreateUriPermissionLocked(
   5873             String sourcePkg, String targetPkg, int targetUid, Uri uri) {
   5874         ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
   5875         if (targetUris == null) {
   5876             targetUris = Maps.newArrayMap();
   5877             mGrantedUriPermissions.put(targetUid, targetUris);
   5878         }
   5879 
   5880         UriPermission perm = targetUris.get(uri);
   5881         if (perm == null) {
   5882             perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
   5883             targetUris.put(uri, perm);
   5884         }
   5885 
   5886         return perm;
   5887     }
   5888 
   5889     private final boolean checkUriPermissionLocked(
   5890             Uri uri, int uid, int modeFlags, int minStrength) {
   5891         // Root gets to do everything.
   5892         if (uid == 0) {
   5893             return true;
   5894         }
   5895         ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   5896         if (perms == null) return false;
   5897         UriPermission perm = perms.get(uri);
   5898         if (perm == null) return false;
   5899         return perm.getStrength(modeFlags) >= minStrength;
   5900     }
   5901 
   5902     @Override
   5903     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   5904         enforceNotIsolatedCaller("checkUriPermission");
   5905 
   5906         // Another redirected-binder-call permissions check as in
   5907         // {@link checkComponentPermission}.
   5908         Identity tlsIdentity = sCallerIdentity.get();
   5909         if (tlsIdentity != null) {
   5910             uid = tlsIdentity.uid;
   5911             pid = tlsIdentity.pid;
   5912         }
   5913 
   5914         // Our own process gets to do everything.
   5915         if (pid == MY_PID) {
   5916             return PackageManager.PERMISSION_GRANTED;
   5917         }
   5918         synchronized(this) {
   5919             return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
   5920                     ? PackageManager.PERMISSION_GRANTED
   5921                     : PackageManager.PERMISSION_DENIED;
   5922         }
   5923     }
   5924 
   5925     /**
   5926      * Check if the targetPkg can be granted permission to access uri by
   5927      * the callingUid using the given modeFlags.  Throws a security exception
   5928      * if callingUid is not allowed to do this.  Returns the uid of the target
   5929      * if the URI permission grant should be performed; returns -1 if it is not
   5930      * needed (for example targetPkg already has permission to access the URI).
   5931      * If you already know the uid of the target, you can supply it in
   5932      * lastTargetUid else set that to -1.
   5933      */
   5934     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
   5935             Uri uri, int modeFlags, int lastTargetUid) {
   5936         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   5937         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   5938                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   5939         if (modeFlags == 0) {
   5940             return -1;
   5941         }
   5942 
   5943         if (targetPkg != null) {
   5944             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5945                     "Checking grant " + targetPkg + " permission to " + uri);
   5946         }
   5947 
   5948         final IPackageManager pm = AppGlobals.getPackageManager();
   5949 
   5950         // If this is not a content: uri, we can't do anything with it.
   5951         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
   5952             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5953                     "Can't grant URI permission for non-content URI: " + uri);
   5954             return -1;
   5955         }
   5956 
   5957         final String authority = uri.getAuthority();
   5958         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
   5959         if (pi == null) {
   5960             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
   5961             return -1;
   5962         }
   5963 
   5964         int targetUid = lastTargetUid;
   5965         if (targetUid < 0 && targetPkg != null) {
   5966             try {
   5967                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
   5968                 if (targetUid < 0) {
   5969                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5970                             "Can't grant URI permission no uid for: " + targetPkg);
   5971                     return -1;
   5972                 }
   5973             } catch (RemoteException ex) {
   5974                 return -1;
   5975             }
   5976         }
   5977 
   5978         if (targetUid >= 0) {
   5979             // First...  does the target actually need this permission?
   5980             if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
   5981                 // No need to grant the target this permission.
   5982                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   5983                         "Target " + targetPkg + " already has full permission to " + uri);
   5984                 return -1;
   5985             }
   5986         } else {
   5987             // First...  there is no target package, so can anyone access it?
   5988             boolean allowed = pi.exported;
   5989             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   5990                 if (pi.readPermission != null) {
   5991                     allowed = false;
   5992                 }
   5993             }
   5994             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   5995                 if (pi.writePermission != null) {
   5996                     allowed = false;
   5997                 }
   5998             }
   5999             if (allowed) {
   6000                 return -1;
   6001             }
   6002         }
   6003 
   6004         // Second...  is the provider allowing granting of URI permissions?
   6005         if (!pi.grantUriPermissions) {
   6006             throw new SecurityException("Provider " + pi.packageName
   6007                     + "/" + pi.name
   6008                     + " does not allow granting of Uri permissions (uri "
   6009                     + uri + ")");
   6010         }
   6011         if (pi.uriPermissionPatterns != null) {
   6012             final int N = pi.uriPermissionPatterns.length;
   6013             boolean allowed = false;
   6014             for (int i=0; i<N; i++) {
   6015                 if (pi.uriPermissionPatterns[i] != null
   6016                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
   6017                     allowed = true;
   6018                     break;
   6019                 }
   6020             }
   6021             if (!allowed) {
   6022                 throw new SecurityException("Provider " + pi.packageName
   6023                         + "/" + pi.name
   6024                         + " does not allow granting of permission to path of Uri "
   6025                         + uri);
   6026             }
   6027         }
   6028 
   6029         // Third...  does the caller itself have permission to access
   6030         // this uri?
   6031         if (callingUid != Process.myUid()) {
   6032             if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   6033                 // Require they hold a strong enough Uri permission
   6034                 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
   6035                         : UriPermission.STRENGTH_OWNED;
   6036                 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
   6037                     throw new SecurityException("Uid " + callingUid
   6038                             + " does not have permission to uri " + uri);
   6039                 }
   6040             }
   6041         }
   6042 
   6043         return targetUid;
   6044     }
   6045 
   6046     @Override
   6047     public int checkGrantUriPermission(int callingUid, String targetPkg,
   6048             Uri uri, int modeFlags) {
   6049         enforceNotIsolatedCaller("checkGrantUriPermission");
   6050         synchronized(this) {
   6051             return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   6052         }
   6053     }
   6054 
   6055     void grantUriPermissionUncheckedLocked(
   6056             int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
   6057         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
   6058         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6059                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6060         if (modeFlags == 0) {
   6061             return;
   6062         }
   6063 
   6064         // So here we are: the caller has the assumed permission
   6065         // to the uri, and the target doesn't.  Let's now give this to
   6066         // the target.
   6067 
   6068         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6069                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
   6070 
   6071         final String authority = uri.getAuthority();
   6072         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
   6073         if (pi == null) {
   6074             Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
   6075             return;
   6076         }
   6077 
   6078         final UriPermission perm = findOrCreateUriPermissionLocked(
   6079                 pi.packageName, targetPkg, targetUid, uri);
   6080         perm.grantModes(modeFlags, persistable, owner);
   6081     }
   6082 
   6083     void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
   6084             int modeFlags, UriPermissionOwner owner) {
   6085         if (targetPkg == null) {
   6086             throw new NullPointerException("targetPkg");
   6087         }
   6088 
   6089         int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
   6090         if (targetUid < 0) {
   6091             return;
   6092         }
   6093 
   6094         grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
   6095     }
   6096 
   6097     static class NeededUriGrants extends ArrayList<Uri> {
   6098         final String targetPkg;
   6099         final int targetUid;
   6100         final int flags;
   6101 
   6102         NeededUriGrants(String targetPkg, int targetUid, int flags) {
   6103             this.targetPkg = targetPkg;
   6104             this.targetUid = targetUid;
   6105             this.flags = flags;
   6106         }
   6107     }
   6108 
   6109     /**
   6110      * Like checkGrantUriPermissionLocked, but takes an Intent.
   6111      */
   6112     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
   6113             String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
   6114         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6115                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
   6116                 + " clip=" + (intent != null ? intent.getClipData() : null)
   6117                 + " from " + intent + "; flags=0x"
   6118                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
   6119 
   6120         if (targetPkg == null) {
   6121             throw new NullPointerException("targetPkg");
   6122         }
   6123 
   6124         if (intent == null) {
   6125             return null;
   6126         }
   6127         Uri data = intent.getData();
   6128         ClipData clip = intent.getClipData();
   6129         if (data == null && clip == null) {
   6130             return null;
   6131         }
   6132 
   6133         if (data != null) {
   6134             int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
   6135                 mode, needed != null ? needed.targetUid : -1);
   6136             if (targetUid > 0) {
   6137                 if (needed == null) {
   6138                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
   6139                 }
   6140                 needed.add(data);
   6141             }
   6142         }
   6143         if (clip != null) {
   6144             for (int i=0; i<clip.getItemCount(); i++) {
   6145                 Uri uri = clip.getItemAt(i).getUri();
   6146                 if (uri != null) {
   6147                     int targetUid = -1;
   6148                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
   6149                             mode, needed != null ? needed.targetUid : -1);
   6150                     if (targetUid > 0) {
   6151                         if (needed == null) {
   6152                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
   6153                         }
   6154                         needed.add(uri);
   6155                     }
   6156                 } else {
   6157                     Intent clipIntent = clip.getItemAt(i).getIntent();
   6158                     if (clipIntent != null) {
   6159                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
   6160                                 callingUid, targetPkg, clipIntent, mode, needed);
   6161                         if (newNeeded != null) {
   6162                             needed = newNeeded;
   6163                         }
   6164                     }
   6165                 }
   6166             }
   6167         }
   6168 
   6169         return needed;
   6170     }
   6171 
   6172     /**
   6173      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
   6174      */
   6175     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
   6176             UriPermissionOwner owner) {
   6177         if (needed != null) {
   6178             for (int i=0; i<needed.size(); i++) {
   6179                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
   6180                         needed.get(i), needed.flags, owner);
   6181             }
   6182         }
   6183     }
   6184 
   6185     void grantUriPermissionFromIntentLocked(int callingUid,
   6186             String targetPkg, Intent intent, UriPermissionOwner owner) {
   6187         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
   6188                 intent, intent != null ? intent.getFlags() : 0, null);
   6189         if (needed == null) {
   6190             return;
   6191         }
   6192 
   6193         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
   6194     }
   6195 
   6196     @Override
   6197     public void grantUriPermission(IApplicationThread caller, String targetPkg,
   6198             Uri uri, int modeFlags) {
   6199         enforceNotIsolatedCaller("grantUriPermission");
   6200         synchronized(this) {
   6201             final ProcessRecord r = getRecordForAppLocked(caller);
   6202             if (r == null) {
   6203                 throw new SecurityException("Unable to find app for caller "
   6204                         + caller
   6205                         + " when granting permission to uri " + uri);
   6206             }
   6207             if (targetPkg == null) {
   6208                 throw new IllegalArgumentException("null target");
   6209             }
   6210             if (uri == null) {
   6211                 throw new IllegalArgumentException("null uri");
   6212             }
   6213 
   6214             // Persistable only supported through Intents
   6215             Preconditions.checkFlagsArgument(modeFlags,
   6216                     Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6217 
   6218             grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
   6219                     null);
   6220         }
   6221     }
   6222 
   6223     void removeUriPermissionIfNeededLocked(UriPermission perm) {
   6224         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
   6225                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
   6226             ArrayMap<Uri, UriPermission> perms
   6227                     = mGrantedUriPermissions.get(perm.targetUid);
   6228             if (perms != null) {
   6229                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6230                         "Removing " + perm.targetUid + " permission to " + perm.uri);
   6231                 perms.remove(perm.uri);
   6232                 if (perms.size() == 0) {
   6233                     mGrantedUriPermissions.remove(perm.targetUid);
   6234                 }
   6235             }
   6236         }
   6237     }
   6238 
   6239     private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
   6240         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
   6241 
   6242         final IPackageManager pm = AppGlobals.getPackageManager();
   6243         final String authority = uri.getAuthority();
   6244         final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
   6245         if (pi == null) {
   6246             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
   6247             return;
   6248         }
   6249 
   6250         // Does the caller have this permission on the URI?
   6251         if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
   6252             // Right now, if you are not the original owner of the permission,
   6253             // you are not allowed to revoke it.
   6254             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
   6255                 throw new SecurityException("Uid " + callingUid
   6256                         + " does not have permission to uri " + uri);
   6257             //}
   6258         }
   6259 
   6260         boolean persistChanged = false;
   6261 
   6262         // Go through all of the permissions and remove any that match.
   6263         final List<String> SEGMENTS = uri.getPathSegments();
   6264         if (SEGMENTS != null) {
   6265             final int NS = SEGMENTS.size();
   6266             int N = mGrantedUriPermissions.size();
   6267             for (int i=0; i<N; i++) {
   6268                 ArrayMap<Uri, UriPermission> perms
   6269                         = mGrantedUriPermissions.valueAt(i);
   6270                 Iterator<UriPermission> it = perms.values().iterator();
   6271             toploop:
   6272                 while (it.hasNext()) {
   6273                     UriPermission perm = it.next();
   6274                     Uri targetUri = perm.uri;
   6275                     if (!authority.equals(targetUri.getAuthority())) {
   6276                         continue;
   6277                     }
   6278                     List<String> targetSegments = targetUri.getPathSegments();
   6279                     if (targetSegments == null) {
   6280                         continue;
   6281                     }
   6282                     if (targetSegments.size() < NS) {
   6283                         continue;
   6284                     }
   6285                     for (int j=0; j<NS; j++) {
   6286                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
   6287                             continue toploop;
   6288                         }
   6289                     }
   6290                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
   6291                             "Revoking " + perm.targetUid + " permission to " + perm.uri);
   6292                     persistChanged |= perm.clearModes(modeFlags, true);
   6293                     if (perm.modeFlags == 0) {
   6294                         it.remove();
   6295                     }
   6296                 }
   6297                 if (perms.size() == 0) {
   6298                     mGrantedUriPermissions.remove(
   6299                             mGrantedUriPermissions.keyAt(i));
   6300                     N--;
   6301                     i--;
   6302                 }
   6303             }
   6304         }
   6305 
   6306         if (persistChanged) {
   6307             schedulePersistUriGrants();
   6308         }
   6309     }
   6310 
   6311     @Override
   6312     public void revokeUriPermission(IApplicationThread caller, Uri uri,
   6313             int modeFlags) {
   6314         enforceNotIsolatedCaller("revokeUriPermission");
   6315         synchronized(this) {
   6316             final ProcessRecord r = getRecordForAppLocked(caller);
   6317             if (r == null) {
   6318                 throw new SecurityException("Unable to find app for caller "
   6319                         + caller
   6320                         + " when revoking permission to uri " + uri);
   6321             }
   6322             if (uri == null) {
   6323                 Slog.w(TAG, "revokeUriPermission: null uri");
   6324                 return;
   6325             }
   6326 
   6327             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
   6328                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6329             if (modeFlags == 0) {
   6330                 return;
   6331             }
   6332 
   6333             final IPackageManager pm = AppGlobals.getPackageManager();
   6334             final String authority = uri.getAuthority();
   6335             final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
   6336             if (pi == null) {
   6337                 Slog.w(TAG, "No content provider found for permission revoke: "
   6338                         + uri.toSafeString());
   6339                 return;
   6340             }
   6341 
   6342             revokeUriPermissionLocked(r.uid, uri, modeFlags);
   6343         }
   6344     }
   6345 
   6346     /**
   6347      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
   6348      * given package.
   6349      *
   6350      * @param packageName Package name to match, or {@code null} to apply to all
   6351      *            packages.
   6352      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
   6353      *            to all users.
   6354      * @param persistable If persistable grants should be removed.
   6355      */
   6356     private void removeUriPermissionsForPackageLocked(
   6357             String packageName, int userHandle, boolean persistable) {
   6358         if (userHandle == UserHandle.USER_ALL && packageName == null) {
   6359             throw new IllegalArgumentException("Must narrow by either package or user");
   6360         }
   6361 
   6362         boolean persistChanged = false;
   6363 
   6364         final int size = mGrantedUriPermissions.size();
   6365         for (int i = 0; i < size; i++) {
   6366             // Only inspect grants matching user
   6367             if (userHandle == UserHandle.USER_ALL
   6368                     || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
   6369                 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
   6370                         .values().iterator();
   6371                 while (it.hasNext()) {
   6372                     final UriPermission perm = it.next();
   6373 
   6374                     // Only inspect grants matching package
   6375                     if (packageName == null || perm.sourcePkg.equals(packageName)
   6376                             || perm.targetPkg.equals(packageName)) {
   6377                         persistChanged |= perm.clearModes(~0, persistable);
   6378 
   6379                         // Only remove when no modes remain; any persisted grants
   6380                         // will keep this alive.
   6381                         if (perm.modeFlags == 0) {
   6382                             it.remove();
   6383                         }
   6384                     }
   6385                 }
   6386             }
   6387         }
   6388 
   6389         if (persistChanged) {
   6390             schedulePersistUriGrants();
   6391         }
   6392     }
   6393 
   6394     @Override
   6395     public IBinder newUriPermissionOwner(String name) {
   6396         enforceNotIsolatedCaller("newUriPermissionOwner");
   6397         synchronized(this) {
   6398             UriPermissionOwner owner = new UriPermissionOwner(this, name);
   6399             return owner.getExternalTokenLocked();
   6400         }
   6401     }
   6402 
   6403     @Override
   6404     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
   6405             Uri uri, int modeFlags) {
   6406         synchronized(this) {
   6407             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   6408             if (owner == null) {
   6409                 throw new IllegalArgumentException("Unknown owner: " + token);
   6410             }
   6411             if (fromUid != Binder.getCallingUid()) {
   6412                 if (Binder.getCallingUid() != Process.myUid()) {
   6413                     // Only system code can grant URI permissions on behalf
   6414                     // of other users.
   6415                     throw new SecurityException("nice try");
   6416                 }
   6417             }
   6418             if (targetPkg == null) {
   6419                 throw new IllegalArgumentException("null target");
   6420             }
   6421             if (uri == null) {
   6422                 throw new IllegalArgumentException("null uri");
   6423             }
   6424 
   6425             grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
   6426         }
   6427     }
   6428 
   6429     @Override
   6430     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
   6431         synchronized(this) {
   6432             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
   6433             if (owner == null) {
   6434                 throw new IllegalArgumentException("Unknown owner: " + token);
   6435             }
   6436 
   6437             if (uri == null) {
   6438                 owner.removeUriPermissionsLocked(mode);
   6439             } else {
   6440                 owner.removeUriPermissionLocked(uri, mode);
   6441             }
   6442         }
   6443     }
   6444 
   6445     private void schedulePersistUriGrants() {
   6446         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
   6447             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
   6448                     10 * DateUtils.SECOND_IN_MILLIS);
   6449         }
   6450     }
   6451 
   6452     private void writeGrantedUriPermissions() {
   6453         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
   6454 
   6455         // Snapshot permissions so we can persist without lock
   6456         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
   6457         synchronized (this) {
   6458             final int size = mGrantedUriPermissions.size();
   6459             for (int i = 0 ; i < size; i++) {
   6460                 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
   6461                     if (perm.persistedModeFlags != 0) {
   6462                         persist.add(perm.snapshot());
   6463                     }
   6464                 }
   6465             }
   6466         }
   6467 
   6468         FileOutputStream fos = null;
   6469         try {
   6470             fos = mGrantFile.startWrite();
   6471 
   6472             XmlSerializer out = new FastXmlSerializer();
   6473             out.setOutput(fos, "utf-8");
   6474             out.startDocument(null, true);
   6475             out.startTag(null, TAG_URI_GRANTS);
   6476             for (UriPermission.Snapshot perm : persist) {
   6477                 out.startTag(null, TAG_URI_GRANT);
   6478                 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
   6479                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
   6480                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
   6481                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
   6482                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
   6483                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
   6484                 out.endTag(null, TAG_URI_GRANT);
   6485             }
   6486             out.endTag(null, TAG_URI_GRANTS);
   6487             out.endDocument();
   6488 
   6489             mGrantFile.finishWrite(fos);
   6490         } catch (IOException e) {
   6491             if (fos != null) {
   6492                 mGrantFile.failWrite(fos);
   6493             }
   6494         }
   6495     }
   6496 
   6497     private void readGrantedUriPermissionsLocked() {
   6498         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
   6499 
   6500         final long now = System.currentTimeMillis();
   6501 
   6502         FileInputStream fis = null;
   6503         try {
   6504             fis = mGrantFile.openRead();
   6505             final XmlPullParser in = Xml.newPullParser();
   6506             in.setInput(fis, null);
   6507 
   6508             int type;
   6509             while ((type = in.next()) != END_DOCUMENT) {
   6510                 final String tag = in.getName();
   6511                 if (type == START_TAG) {
   6512                     if (TAG_URI_GRANT.equals(tag)) {
   6513                         final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
   6514                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
   6515                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
   6516                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
   6517                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
   6518                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
   6519 
   6520                         // Sanity check that provider still belongs to source package
   6521                         final ProviderInfo pi = getProviderInfoLocked(
   6522                                 uri.getAuthority(), userHandle);
   6523                         if (pi != null && sourcePkg.equals(pi.packageName)) {
   6524                             int targetUid = -1;
   6525                             try {
   6526                                 targetUid = AppGlobals.getPackageManager()
   6527                                         .getPackageUid(targetPkg, userHandle);
   6528                             } catch (RemoteException e) {
   6529                             }
   6530                             if (targetUid != -1) {
   6531                                 final UriPermission perm = findOrCreateUriPermissionLocked(
   6532                                         sourcePkg, targetPkg, targetUid, uri);
   6533                                 perm.initPersistedModes(modeFlags, createdTime);
   6534                             }
   6535                         } else {
   6536                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
   6537                                     + " but instead found " + pi);
   6538                         }
   6539                     }
   6540                 }
   6541             }
   6542         } catch (FileNotFoundException e) {
   6543             // Missing grants is okay
   6544         } catch (IOException e) {
   6545             Log.wtf(TAG, "Failed reading Uri grants", e);
   6546         } catch (XmlPullParserException e) {
   6547             Log.wtf(TAG, "Failed reading Uri grants", e);
   6548         } finally {
   6549             IoUtils.closeQuietly(fis);
   6550         }
   6551     }
   6552 
   6553     @Override
   6554     public void takePersistableUriPermission(Uri uri, int modeFlags) {
   6555         enforceNotIsolatedCaller("takePersistableUriPermission");
   6556 
   6557         Preconditions.checkFlagsArgument(modeFlags,
   6558                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6559 
   6560         synchronized (this) {
   6561             final int callingUid = Binder.getCallingUid();
   6562             final UriPermission perm = findUriPermissionLocked(callingUid, uri);
   6563             if (perm == null) {
   6564                 throw new SecurityException("No permission grant found for UID " + callingUid
   6565                         + " and Uri " + uri.toSafeString());
   6566             }
   6567 
   6568             boolean persistChanged = perm.takePersistableModes(modeFlags);
   6569             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
   6570 
   6571             if (persistChanged) {
   6572                 schedulePersistUriGrants();
   6573             }
   6574         }
   6575     }
   6576 
   6577     @Override
   6578     public void releasePersistableUriPermission(Uri uri, int modeFlags) {
   6579         enforceNotIsolatedCaller("releasePersistableUriPermission");
   6580 
   6581         Preconditions.checkFlagsArgument(modeFlags,
   6582                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   6583 
   6584         synchronized (this) {
   6585             final int callingUid = Binder.getCallingUid();
   6586 
   6587             final UriPermission perm = findUriPermissionLocked(callingUid, uri);
   6588             if (perm == null) {
   6589                 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
   6590                         + uri.toSafeString());
   6591                 return;
   6592             }
   6593 
   6594             final boolean persistChanged = perm.releasePersistableModes(modeFlags);
   6595             removeUriPermissionIfNeededLocked(perm);
   6596             if (persistChanged) {
   6597                 schedulePersistUriGrants();
   6598             }
   6599         }
   6600     }
   6601 
   6602     /**
   6603      * Prune any older {@link UriPermission} for the given UID until outstanding
   6604      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
   6605      *
   6606      * @return if any mutations occured that require persisting.
   6607      */
   6608     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
   6609         final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
   6610         if (perms == null) return false;
   6611         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
   6612 
   6613         final ArrayList<UriPermission> persisted = Lists.newArrayList();
   6614         for (UriPermission perm : perms.values()) {
   6615             if (perm.persistedModeFlags != 0) {
   6616                 persisted.add(perm);
   6617             }
   6618         }
   6619 
   6620         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
   6621         if (trimCount <= 0) return false;
   6622 
   6623         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
   6624         for (int i = 0; i < trimCount; i++) {
   6625             final UriPermission perm = persisted.get(i);
   6626 
   6627             if (DEBUG_URI_PERMISSION) {
   6628                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
   6629             }
   6630 
   6631             perm.releasePersistableModes(~0);
   6632             removeUriPermissionIfNeededLocked(perm);
   6633         }
   6634 
   6635         return true;
   6636     }
   6637 
   6638     @Override
   6639     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
   6640             String packageName, boolean incoming) {
   6641         enforceNotIsolatedCaller("getPersistedUriPermissions");
   6642         Preconditions.checkNotNull(packageName, "packageName");
   6643 
   6644         final int callingUid = Binder.getCallingUid();
   6645         final IPackageManager pm = AppGlobals.getPackageManager();
   6646         try {
   6647             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
   6648             if (packageUid != callingUid) {
   6649                 throw new SecurityException(
   6650                         "Package " + packageName + " does not belong to calling UID " + callingUid);
   6651             }
   6652         } catch (RemoteException e) {
   6653             throw new SecurityException("Failed to verify package name ownership");
   6654         }
   6655 
   6656         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
   6657         synchronized (this) {
   6658             if (incoming) {
   6659                 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   6660                 if (perms == null) {
   6661                     Slog.w(TAG, "No permission grants found for " + packageName);
   6662                 } else {
   6663                     final int size = perms.size();
   6664                     for (int i = 0; i < size; i++) {
   6665                         final UriPermission perm = perms.valueAt(i);
   6666                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
   6667                             result.add(perm.buildPersistedPublicApiObject());
   6668                         }
   6669                     }
   6670                 }
   6671             } else {
   6672                 final int size = mGrantedUriPermissions.size();
   6673                 for (int i = 0; i < size; i++) {
   6674                     final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
   6675                     final int permsSize = perms.size();
   6676                     for (int j = 0; j < permsSize; j++) {
   6677                         final UriPermission perm = perms.valueAt(j);
   6678                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
   6679                             result.add(perm.buildPersistedPublicApiObject());
   6680                         }
   6681                     }
   6682                 }
   6683             }
   6684         }
   6685         return new ParceledListSlice<android.content.UriPermission>(result);
   6686     }
   6687 
   6688     @Override
   6689     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
   6690         synchronized (this) {
   6691             ProcessRecord app =
   6692                 who != null ? getRecordForAppLocked(who) : null;
   6693             if (app == null) return;
   6694 
   6695             Message msg = Message.obtain();
   6696             msg.what = WAIT_FOR_DEBUGGER_MSG;
   6697             msg.obj = app;
   6698             msg.arg1 = waiting ? 1 : 0;
   6699             mHandler.sendMessage(msg);
   6700         }
   6701     }
   6702 
   6703     @Override
   6704     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
   6705         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
   6706         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
   6707         outInfo.availMem = Process.getFreeMemory();
   6708         outInfo.totalMem = Process.getTotalMemory();
   6709         outInfo.threshold = homeAppMem;
   6710         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
   6711         outInfo.hiddenAppThreshold = cachedAppMem;
   6712         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
   6713                 ProcessList.SERVICE_ADJ);
   6714         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
   6715                 ProcessList.VISIBLE_APP_ADJ);
   6716         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
   6717                 ProcessList.FOREGROUND_APP_ADJ);
   6718     }
   6719 
   6720     // =========================================================
   6721     // TASK MANAGEMENT
   6722     // =========================================================
   6723 
   6724     @Override
   6725     public List<RunningTaskInfo> getTasks(int maxNum, int flags,
   6726                          IThumbnailReceiver receiver) {
   6727         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
   6728 
   6729         PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
   6730         ActivityRecord topRecord = null;
   6731 
   6732         synchronized(this) {
   6733             if (localLOGV) Slog.v(
   6734                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
   6735                 + ", receiver=" + receiver);
   6736 
   6737             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
   6738                     != PackageManager.PERMISSION_GRANTED) {
   6739                 if (receiver != null) {
   6740                     // If the caller wants to wait for pending thumbnails,
   6741                     // it ain't gonna get them.
   6742                     try {
   6743                         receiver.finished();
   6744                     } catch (RemoteException ex) {
   6745                     }
   6746                 }
   6747                 String msg = "Permission Denial: getTasks() from pid="
   6748                         + Binder.getCallingPid()
   6749                         + ", uid=" + Binder.getCallingUid()
   6750                         + " requires " + android.Manifest.permission.GET_TASKS;
   6751                 Slog.w(TAG, msg);
   6752                 throw new SecurityException(msg);
   6753             }
   6754 
   6755             // TODO: Improve with MRU list from all ActivityStacks.
   6756             topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
   6757 
   6758             if (!pending.pendingRecords.isEmpty()) {
   6759                 mPendingThumbnails.add(pending);
   6760             }
   6761         }
   6762 
   6763         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
   6764 
   6765         if (topRecord != null) {
   6766             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
   6767             try {
   6768                 IApplicationThread topThumbnail = topRecord.app.thread;
   6769                 topThumbnail.requestThumbnail(topRecord.appToken);
   6770             } catch (Exception e) {
   6771                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
   6772                 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
   6773             }
   6774         }
   6775 
   6776         if (pending == null && receiver != null) {
   6777             // In this case all thumbnails were available and the client
   6778             // is being asked to be told when the remaining ones come in...
   6779             // which is unusually, since the top-most currently running
   6780             // activity should never have a canned thumbnail!  Oh well.
   6781             try {
   6782                 receiver.finished();
   6783             } catch (RemoteException ex) {
   6784             }
   6785         }
   6786 
   6787         return list;
   6788     }
   6789 
   6790     TaskRecord getMostRecentTask() {
   6791         return mRecentTasks.get(0);
   6792     }
   6793 
   6794     @Override
   6795     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
   6796             int flags, int userId) {
   6797         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   6798                 false, true, "getRecentTasks", null);
   6799 
   6800         synchronized (this) {
   6801             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
   6802                     "getRecentTasks()");
   6803             final boolean detailed = checkCallingPermission(
   6804                     android.Manifest.permission.GET_DETAILED_TASKS)
   6805                     == PackageManager.PERMISSION_GRANTED;
   6806 
   6807             IPackageManager pm = AppGlobals.getPackageManager();
   6808 
   6809             final int N = mRecentTasks.size();
   6810             ArrayList<ActivityManager.RecentTaskInfo> res
   6811                     = new ArrayList<ActivityManager.RecentTaskInfo>(
   6812                             maxNum < N ? maxNum : N);
   6813             for (int i=0; i<N && maxNum > 0; i++) {
   6814                 TaskRecord tr = mRecentTasks.get(i);
   6815                 // Only add calling user's recent tasks
   6816                 if (tr.userId != userId) continue;
   6817                 // Return the entry if desired by the caller.  We always return
   6818                 // the first entry, because callers always expect this to be the
   6819                 // foreground app.  We may filter others if the caller has
   6820                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
   6821                 // we should exclude the entry.
   6822 
   6823                 if (i == 0
   6824                         || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
   6825                         || (tr.intent == null)
   6826                         || ((tr.intent.getFlags()
   6827                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
   6828                     ActivityManager.RecentTaskInfo rti
   6829                             = new ActivityManager.RecentTaskInfo();
   6830                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
   6831                     rti.persistentId = tr.taskId;
   6832                     rti.baseIntent = new Intent(
   6833                             tr.intent != null ? tr.intent : tr.affinityIntent);
   6834                     if (!detailed) {
   6835                         rti.baseIntent.replaceExtras((Bundle)null);
   6836                     }
   6837                     rti.origActivity = tr.origActivity;
   6838                     rti.description = tr.lastDescription;
   6839                     rti.stackId = tr.stack.mStackId;
   6840 
   6841                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
   6842                         // Check whether this activity is currently available.
   6843                         try {
   6844                             if (rti.origActivity != null) {
   6845                                 if (pm.getActivityInfo(rti.origActivity, 0, userId)
   6846                                         == null) {
   6847                                     continue;
   6848                                 }
   6849                             } else if (rti.baseIntent != null) {
   6850                                 if (pm.queryIntentActivities(rti.baseIntent,
   6851                                         null, 0, userId) == null) {
   6852                                     continue;
   6853                                 }
   6854                             }
   6855                         } catch (RemoteException e) {
   6856                             // Will never happen.
   6857                         }
   6858                     }
   6859 
   6860                     res.add(rti);
   6861                     maxNum--;
   6862                 }
   6863             }
   6864             return res;
   6865         }
   6866     }
   6867 
   6868     private TaskRecord recentTaskForIdLocked(int id) {
   6869         final int N = mRecentTasks.size();
   6870             for (int i=0; i<N; i++) {
   6871                 TaskRecord tr = mRecentTasks.get(i);
   6872                 if (tr.taskId == id) {
   6873                     return tr;
   6874                 }
   6875             }
   6876             return null;
   6877     }
   6878 
   6879     @Override
   6880     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
   6881         synchronized (this) {
   6882             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   6883                     "getTaskThumbnails()");
   6884             TaskRecord tr = recentTaskForIdLocked(id);
   6885             if (tr != null) {
   6886                 return tr.getTaskThumbnailsLocked();
   6887             }
   6888         }
   6889         return null;
   6890     }
   6891 
   6892     @Override
   6893     public Bitmap getTaskTopThumbnail(int id) {
   6894         synchronized (this) {
   6895             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
   6896                     "getTaskTopThumbnail()");
   6897             TaskRecord tr = recentTaskForIdLocked(id);
   6898             if (tr != null) {
   6899                 return tr.getTaskTopThumbnailLocked();
   6900             }
   6901         }
   6902         return null;
   6903     }
   6904 
   6905     @Override
   6906     public boolean removeSubTask(int taskId, int subTaskIndex) {
   6907         synchronized (this) {
   6908             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   6909                     "removeSubTask()");
   6910             long ident = Binder.clearCallingIdentity();
   6911             try {
   6912                 TaskRecord tr = recentTaskForIdLocked(taskId);
   6913                 if (tr != null) {
   6914                     return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
   6915                 }
   6916                 return false;
   6917             } finally {
   6918                 Binder.restoreCallingIdentity(ident);
   6919             }
   6920         }
   6921     }
   6922 
   6923     private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
   6924         if (!pr.killedByAm) {
   6925             Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
   6926             EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
   6927                     pr.processName, pr.setAdj, reason);
   6928             pr.killedByAm = true;
   6929             Process.killProcessQuiet(pr.pid);
   6930         }
   6931     }
   6932 
   6933     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
   6934         tr.disposeThumbnail();
   6935         mRecentTasks.remove(tr);
   6936         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
   6937         Intent baseIntent = new Intent(
   6938                 tr.intent != null ? tr.intent : tr.affinityIntent);
   6939         ComponentName component = baseIntent.getComponent();
   6940         if (component == null) {
   6941             Slog.w(TAG, "Now component for base intent of task: " + tr);
   6942             return;
   6943         }
   6944 
   6945         // Find any running services associated with this app.
   6946         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
   6947 
   6948         if (killProcesses) {
   6949             // Find any running processes associated with this app.
   6950             final String pkg = component.getPackageName();
   6951             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
   6952             ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
   6953             for (int i=0; i<pmap.size(); i++) {
   6954                 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
   6955                 for (int j=0; j<uids.size(); j++) {
   6956                     ProcessRecord proc = uids.valueAt(j);
   6957                     if (proc.userId != tr.userId) {
   6958                         continue;
   6959                     }
   6960                     if (!proc.pkgList.containsKey(pkg)) {
   6961                         continue;
   6962                     }
   6963                     procs.add(proc);
   6964                 }
   6965             }
   6966 
   6967             // Kill the running processes.
   6968             for (int i=0; i<procs.size(); i++) {
   6969                 ProcessRecord pr = procs.get(i);
   6970                 if (pr == mHomeProcess) {
   6971                     // Don't kill the home process along with tasks from the same package.
   6972                     continue;
   6973                 }
   6974                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   6975                     killUnneededProcessLocked(pr, "remove task");
   6976                 } else {
   6977                     pr.waitingToKill = "remove task";
   6978                 }
   6979             }
   6980         }
   6981     }
   6982 
   6983     @Override
   6984     public boolean removeTask(int taskId, int flags) {
   6985         synchronized (this) {
   6986             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
   6987                     "removeTask()");
   6988             long ident = Binder.clearCallingIdentity();
   6989             try {
   6990                 TaskRecord tr = recentTaskForIdLocked(taskId);
   6991                 if (tr != null) {
   6992                     ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
   6993                     if (r != null) {
   6994                         cleanUpRemovedTaskLocked(tr, flags);
   6995                         return true;
   6996                     }
   6997                     if (tr.mActivities.size() == 0) {
   6998                         // Caller is just removing a recent task that is
   6999                         // not actively running.  That is easy!
   7000                         cleanUpRemovedTaskLocked(tr, flags);
   7001                         return true;
   7002                     }
   7003                     Slog.w(TAG, "removeTask: task " + taskId
   7004                             + " does not have activities to remove, "
   7005                             + " but numActivities=" + tr.numActivities
   7006                             + ": " + tr);
   7007                 }
   7008             } finally {
   7009                 Binder.restoreCallingIdentity(ident);
   7010             }
   7011         }
   7012         return false;
   7013     }
   7014 
   7015     /**
   7016      * TODO: Add mController hook
   7017      */
   7018     @Override
   7019     public void moveTaskToFront(int task, int flags, Bundle options) {
   7020         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7021                 "moveTaskToFront()");
   7022 
   7023         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
   7024         synchronized(this) {
   7025             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7026                     Binder.getCallingUid(), "Task to front")) {
   7027                 ActivityOptions.abort(options);
   7028                 return;
   7029             }
   7030             final long origId = Binder.clearCallingIdentity();
   7031             try {
   7032                 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
   7033             } finally {
   7034                 Binder.restoreCallingIdentity(origId);
   7035             }
   7036             ActivityOptions.abort(options);
   7037         }
   7038     }
   7039 
   7040     @Override
   7041     public void moveTaskToBack(int taskId) {
   7042         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7043                 "moveTaskToBack()");
   7044 
   7045         synchronized(this) {
   7046             TaskRecord tr = recentTaskForIdLocked(taskId);
   7047             if (tr != null) {
   7048                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
   7049                 ActivityStack stack = tr.stack;
   7050                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
   7051                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7052                             Binder.getCallingUid(), "Task to back")) {
   7053                         return;
   7054                     }
   7055                 }
   7056                 final long origId = Binder.clearCallingIdentity();
   7057                 try {
   7058                     stack.moveTaskToBackLocked(taskId, null);
   7059                 } finally {
   7060                     Binder.restoreCallingIdentity(origId);
   7061                 }
   7062             }
   7063         }
   7064     }
   7065 
   7066     /**
   7067      * Moves an activity, and all of the other activities within the same task, to the bottom
   7068      * of the history stack.  The activity's order within the task is unchanged.
   7069      *
   7070      * @param token A reference to the activity we wish to move
   7071      * @param nonRoot If false then this only works if the activity is the root
   7072      *                of a task; if true it will work for any activity in a task.
   7073      * @return Returns true if the move completed, false if not.
   7074      */
   7075     @Override
   7076     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
   7077         enforceNotIsolatedCaller("moveActivityTaskToBack");
   7078         synchronized(this) {
   7079             final long origId = Binder.clearCallingIdentity();
   7080             int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
   7081             if (taskId >= 0) {
   7082                 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
   7083             }
   7084             Binder.restoreCallingIdentity(origId);
   7085         }
   7086         return false;
   7087     }
   7088 
   7089     @Override
   7090     public void moveTaskBackwards(int task) {
   7091         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
   7092                 "moveTaskBackwards()");
   7093 
   7094         synchronized(this) {
   7095             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
   7096                     Binder.getCallingUid(), "Task backwards")) {
   7097                 return;
   7098             }
   7099             final long origId = Binder.clearCallingIdentity();
   7100             moveTaskBackwardsLocked(task);
   7101             Binder.restoreCallingIdentity(origId);
   7102         }
   7103     }
   7104 
   7105     private final void moveTaskBackwardsLocked(int task) {
   7106         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
   7107     }
   7108 
   7109     @Override
   7110     public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
   7111         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7112                 "createStack()");
   7113         if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
   7114                 relativeStackBoxId + " position=" + position + " weight=" + weight);
   7115         synchronized (this) {
   7116             long ident = Binder.clearCallingIdentity();
   7117             try {
   7118                 int stackId = mStackSupervisor.createStack();
   7119                 mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
   7120                 if (taskId > 0) {
   7121                     moveTaskToStack(taskId, stackId, true);
   7122                 }
   7123                 return stackId;
   7124             } finally {
   7125                 Binder.restoreCallingIdentity(ident);
   7126             }
   7127         }
   7128     }
   7129 
   7130     @Override
   7131     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
   7132         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7133                 "moveTaskToStack()");
   7134         if (stackId == HOME_STACK_ID) {
   7135             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
   7136                     new RuntimeException("here").fillInStackTrace());
   7137         }
   7138         synchronized (this) {
   7139             long ident = Binder.clearCallingIdentity();
   7140             try {
   7141                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
   7142                         + stackId + " toTop=" + toTop);
   7143                 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
   7144             } finally {
   7145                 Binder.restoreCallingIdentity(ident);
   7146             }
   7147         }
   7148     }
   7149 
   7150     @Override
   7151     public void resizeStackBox(int stackBoxId, float weight) {
   7152         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7153                 "resizeStackBox()");
   7154         long ident = Binder.clearCallingIdentity();
   7155         try {
   7156             mWindowManager.resizeStackBox(stackBoxId, weight);
   7157         } finally {
   7158             Binder.restoreCallingIdentity(ident);
   7159         }
   7160     }
   7161 
   7162     private ArrayList<StackInfo> getStacks() {
   7163         synchronized (this) {
   7164             ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
   7165             ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
   7166             for (ActivityStack stack : stacks) {
   7167                 ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
   7168                 int stackId = stack.mStackId;
   7169                 stackInfo.stackId = stackId;
   7170                 stackInfo.bounds = mWindowManager.getStackBounds(stackId);
   7171                 ArrayList<TaskRecord> tasks = stack.getAllTasks();
   7172                 final int numTasks = tasks.size();
   7173                 int[] taskIds = new int[numTasks];
   7174                 String[] taskNames = new String[numTasks];
   7175                 for (int i = 0; i < numTasks; ++i) {
   7176                     final TaskRecord task = tasks.get(i);
   7177                     taskIds[i] = task.taskId;
   7178                     taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
   7179                             : task.realActivity != null ? task.realActivity.flattenToString()
   7180                             : task.getTopActivity() != null ? task.getTopActivity().packageName
   7181                             : "unknown";
   7182                 }
   7183                 stackInfo.taskIds = taskIds;
   7184                 stackInfo.taskNames = taskNames;
   7185                 list.add(stackInfo);
   7186             }
   7187             return list;
   7188         }
   7189     }
   7190 
   7191     private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
   7192         final int stackId = stackBoxInfo.stackId;
   7193         if (stackId >= 0) {
   7194             for (StackInfo stackInfo : stackInfos) {
   7195                 if (stackId == stackInfo.stackId) {
   7196                     stackBoxInfo.stack = stackInfo;
   7197                     stackInfos.remove(stackInfo);
   7198                     return;
   7199                 }
   7200             }
   7201         } else {
   7202             addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
   7203             addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
   7204         }
   7205     }
   7206 
   7207     @Override
   7208     public List<StackBoxInfo> getStackBoxes() {
   7209         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7210                 "getStackBoxes()");
   7211         long ident = Binder.clearCallingIdentity();
   7212         try {
   7213             List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
   7214             synchronized (this) {
   7215                 List<StackInfo> stackInfos = getStacks();
   7216                 for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
   7217                     addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
   7218                 }
   7219             }
   7220             return stackBoxInfos;
   7221         } finally {
   7222             Binder.restoreCallingIdentity(ident);
   7223         }
   7224     }
   7225 
   7226     @Override
   7227     public StackBoxInfo getStackBoxInfo(int stackBoxId) {
   7228         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
   7229                 "getStackBoxInfo()");
   7230         long ident = Binder.clearCallingIdentity();
   7231         try {
   7232             List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
   7233             StackBoxInfo info = null;
   7234             synchronized (this) {
   7235                 List<StackInfo> stackInfos = getStacks();
   7236                 for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
   7237                     addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
   7238                     if (stackBoxInfo.stackBoxId == stackBoxId) {
   7239                         info = stackBoxInfo;
   7240                     }
   7241                 }
   7242             }
   7243             return info;
   7244         } finally {
   7245             Binder.restoreCallingIdentity(ident);
   7246         }
   7247     }
   7248 
   7249     @Override
   7250     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
   7251         synchronized(this) {
   7252             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
   7253         }
   7254     }
   7255 
   7256     // =========================================================
   7257     // THUMBNAILS
   7258     // =========================================================
   7259 
   7260     public void reportThumbnail(IBinder token,
   7261             Bitmap thumbnail, CharSequence description) {
   7262         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
   7263         final long origId = Binder.clearCallingIdentity();
   7264         sendPendingThumbnail(null, token, thumbnail, description, true);
   7265         Binder.restoreCallingIdentity(origId);
   7266     }
   7267 
   7268     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
   7269             Bitmap thumbnail, CharSequence description, boolean always) {
   7270         TaskRecord task;
   7271         ArrayList<PendingThumbnailsRecord> receivers = null;
   7272 
   7273         //System.out.println("Send pending thumbnail: " + r);
   7274 
   7275         synchronized(this) {
   7276             if (r == null) {
   7277                 r = ActivityRecord.isInStackLocked(token);
   7278                 if (r == null) {
   7279                     return;
   7280                 }
   7281             }
   7282             if (thumbnail == null && r.thumbHolder != null) {
   7283                 thumbnail = r.thumbHolder.lastThumbnail;
   7284                 description = r.thumbHolder.lastDescription;
   7285             }
   7286             if (thumbnail == null && !always) {
   7287                 // If there is no thumbnail, and this entry is not actually
   7288                 // going away, then abort for now and pick up the next
   7289                 // thumbnail we get.
   7290                 return;
   7291             }
   7292             task = r.task;
   7293 
   7294             int N = mPendingThumbnails.size();
   7295             int i=0;
   7296             while (i<N) {
   7297                 PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
   7298                 //System.out.println("Looking in " + pr.pendingRecords);
   7299                 if (pr.pendingRecords.remove(r)) {
   7300                     if (receivers == null) {
   7301                         receivers = new ArrayList<PendingThumbnailsRecord>();
   7302                     }
   7303                     receivers.add(pr);
   7304                     if (pr.pendingRecords.size() == 0) {
   7305                         pr.finished = true;
   7306                         mPendingThumbnails.remove(i);
   7307                         N--;
   7308                         continue;
   7309                     }
   7310                 }
   7311                 i++;
   7312             }
   7313         }
   7314 
   7315         if (receivers != null) {
   7316             final int N = receivers.size();
   7317             for (int i=0; i<N; i++) {
   7318                 try {
   7319                     PendingThumbnailsRecord pr = receivers.get(i);
   7320                     pr.receiver.newThumbnail(
   7321                         task != null ? task.taskId : -1, thumbnail, description);
   7322                     if (pr.finished) {
   7323                         pr.receiver.finished();
   7324                     }
   7325                 } catch (Exception e) {
   7326                     Slog.w(TAG, "Exception thrown when sending thumbnail", e);
   7327                 }
   7328             }
   7329         }
   7330     }
   7331 
   7332     // =========================================================
   7333     // CONTENT PROVIDERS
   7334     // =========================================================
   7335 
   7336     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   7337         List<ProviderInfo> providers = null;
   7338         try {
   7339             providers = AppGlobals.getPackageManager().
   7340                 queryContentProviders(app.processName, app.uid,
   7341                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
   7342         } catch (RemoteException ex) {
   7343         }
   7344         if (DEBUG_MU)
   7345             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   7346         int userId = app.userId;
   7347         if (providers != null) {
   7348             int N = providers.size();
   7349             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
   7350             for (int i=0; i<N; i++) {
   7351                 ProviderInfo cpi =
   7352                     (ProviderInfo)providers.get(i);
   7353                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   7354                         cpi.name, cpi.flags);
   7355                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
   7356                     // This is a singleton provider, but a user besides the
   7357                     // default user is asking to initialize a process it runs
   7358                     // in...  well, no, it doesn't actually run in this process,
   7359                     // it runs in the process of the default user.  Get rid of it.
   7360                     providers.remove(i);
   7361                     N--;
   7362                     i--;
   7363                     continue;
   7364                 }
   7365 
   7366                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   7367                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
   7368                 if (cpr == null) {
   7369                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
   7370                     mProviderMap.putProviderByClass(comp, cpr);
   7371                 }
   7372                 if (DEBUG_MU)
   7373                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
   7374                 app.pubProviders.put(cpi.name, cpr);
   7375                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
   7376                     // Don't add this if it is a platform component that is marked
   7377                     // to run in multiple processes, because this is actually
   7378                     // part of the framework so doesn't make sense to track as a
   7379                     // separate apk in the process.
   7380                     app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
   7381                 }
   7382                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
   7383             }
   7384         }
   7385         return providers;
   7386     }
   7387 
   7388     /**
   7389      * Check if {@link ProcessRecord} has a possible chance at accessing the
   7390      * given {@link ProviderInfo}. Final permission checking is always done
   7391      * in {@link ContentProvider}.
   7392      */
   7393     private final String checkContentProviderPermissionLocked(
   7394             ProviderInfo cpi, ProcessRecord r) {
   7395         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
   7396         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
   7397         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
   7398                 cpi.applicationInfo.uid, cpi.exported)
   7399                 == PackageManager.PERMISSION_GRANTED) {
   7400             return null;
   7401         }
   7402         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
   7403                 cpi.applicationInfo.uid, cpi.exported)
   7404                 == PackageManager.PERMISSION_GRANTED) {
   7405             return null;
   7406         }
   7407 
   7408         PathPermission[] pps = cpi.pathPermissions;
   7409         if (pps != null) {
   7410             int i = pps.length;
   7411             while (i > 0) {
   7412                 i--;
   7413                 PathPermission pp = pps[i];
   7414                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
   7415                         cpi.applicationInfo.uid, cpi.exported)
   7416                         == PackageManager.PERMISSION_GRANTED) {
   7417                     return null;
   7418                 }
   7419                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
   7420                         cpi.applicationInfo.uid, cpi.exported)
   7421                         == PackageManager.PERMISSION_GRANTED) {
   7422                     return null;
   7423                 }
   7424             }
   7425         }
   7426 
   7427         ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
   7428         if (perms != null) {
   7429             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
   7430                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
   7431                     return null;
   7432                 }
   7433             }
   7434         }
   7435 
   7436         String msg;
   7437         if (!cpi.exported) {
   7438             msg = "Permission Denial: opening provider " + cpi.name
   7439                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   7440                     + ", uid=" + callingUid + ") that is not exported from uid "
   7441                     + cpi.applicationInfo.uid;
   7442         } else {
   7443             msg = "Permission Denial: opening provider " + cpi.name
   7444                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
   7445                     + ", uid=" + callingUid + ") requires "
   7446                     + cpi.readPermission + " or " + cpi.writePermission;
   7447         }
   7448         Slog.w(TAG, msg);
   7449         return msg;
   7450     }
   7451 
   7452     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
   7453             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   7454         if (r != null) {
   7455             for (int i=0; i<r.conProviders.size(); i++) {
   7456                 ContentProviderConnection conn = r.conProviders.get(i);
   7457                 if (conn.provider == cpr) {
   7458                     if (DEBUG_PROVIDER) Slog.v(TAG,
   7459                             "Adding provider requested by "
   7460                             + r.processName + " from process "
   7461                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   7462                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   7463                     if (stable) {
   7464                         conn.stableCount++;
   7465                         conn.numStableIncs++;
   7466                     } else {
   7467                         conn.unstableCount++;
   7468                         conn.numUnstableIncs++;
   7469                     }
   7470                     return conn;
   7471                 }
   7472             }
   7473             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
   7474             if (stable) {
   7475                 conn.stableCount = 1;
   7476                 conn.numStableIncs = 1;
   7477             } else {
   7478                 conn.unstableCount = 1;
   7479                 conn.numUnstableIncs = 1;
   7480             }
   7481             cpr.connections.add(conn);
   7482             r.conProviders.add(conn);
   7483             return conn;
   7484         }
   7485         cpr.addExternalProcessHandleLocked(externalProcessToken);
   7486         return null;
   7487     }
   7488 
   7489     boolean decProviderCountLocked(ContentProviderConnection conn,
   7490             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
   7491         if (conn != null) {
   7492             cpr = conn.provider;
   7493             if (DEBUG_PROVIDER) Slog.v(TAG,
   7494                     "Removing provider requested by "
   7495                     + conn.client.processName + " from process "
   7496                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
   7497                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
   7498             if (stable) {
   7499                 conn.stableCount--;
   7500             } else {
   7501                 conn.unstableCount--;
   7502             }
   7503             if (conn.stableCount == 0 && conn.unstableCount == 0) {
   7504                 cpr.connections.remove(conn);
   7505                 conn.client.conProviders.remove(conn);
   7506                 return true;
   7507             }
   7508             return false;
   7509         }
   7510         cpr.removeExternalProcessHandleLocked(externalProcessToken);
   7511         return false;
   7512     }
   7513 
   7514     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
   7515             String name, IBinder token, boolean stable, int userId) {
   7516         ContentProviderRecord cpr;
   7517         ContentProviderConnection conn = null;
   7518         ProviderInfo cpi = null;
   7519 
   7520         synchronized(this) {
   7521             ProcessRecord r = null;
   7522             if (caller != null) {
   7523                 r = getRecordForAppLocked(caller);
   7524                 if (r == null) {
   7525                     throw new SecurityException(
   7526                             "Unable to find app for caller " + caller
   7527                           + " (pid=" + Binder.getCallingPid()
   7528                           + ") when getting content provider " + name);
   7529                 }
   7530             }
   7531 
   7532             // First check if this content provider has been published...
   7533             cpr = mProviderMap.getProviderByName(name, userId);
   7534             boolean providerRunning = cpr != null;
   7535             if (providerRunning) {
   7536                 cpi = cpr.info;
   7537                 String msg;
   7538                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   7539                     throw new SecurityException(msg);
   7540                 }
   7541 
   7542                 if (r != null && cpr.canRunHere(r)) {
   7543                     // This provider has been published or is in the process
   7544                     // of being published...  but it is also allowed to run
   7545                     // in the caller's process, so don't make a connection
   7546                     // and just let the caller instantiate its own instance.
   7547                     ContentProviderHolder holder = cpr.newHolder(null);
   7548                     // don't give caller the provider object, it needs
   7549                     // to make its own.
   7550                     holder.provider = null;
   7551                     return holder;
   7552                 }
   7553 
   7554                 final long origId = Binder.clearCallingIdentity();
   7555 
   7556                 // In this case the provider instance already exists, so we can
   7557                 // return it right away.
   7558                 conn = incProviderCountLocked(r, cpr, token, stable);
   7559                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
   7560                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   7561                         // If this is a perceptible app accessing the provider,
   7562                         // make sure to count it as being accessed and thus
   7563                         // back up on the LRU list.  This is good because
   7564                         // content providers are often expensive to start.
   7565                         updateLruProcessLocked(cpr.proc, false, null);
   7566                     }
   7567                 }
   7568 
   7569                 if (cpr.proc != null) {
   7570                     if (false) {
   7571                         if (cpr.name.flattenToShortString().equals(
   7572                                 "com.android.providers.calendar/.CalendarProvider2")) {
   7573                             Slog.v(TAG, "****************** KILLING "
   7574                                 + cpr.name.flattenToShortString());
   7575                             Process.killProcess(cpr.proc.pid);
   7576                         }
   7577                     }
   7578                     boolean success = updateOomAdjLocked(cpr.proc);
   7579                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
   7580                     // NOTE: there is still a race here where a signal could be
   7581                     // pending on the process even though we managed to update its
   7582                     // adj level.  Not sure what to do about this, but at least
   7583                     // the race is now smaller.
   7584                     if (!success) {
   7585                         // Uh oh...  it looks like the provider's process
   7586                         // has been killed on us.  We need to wait for a new
   7587                         // process to be started, and make sure its death
   7588                         // doesn't kill our process.
   7589                         Slog.i(TAG,
   7590                                 "Existing provider " + cpr.name.flattenToShortString()
   7591                                 + " is crashing; detaching " + r);
   7592                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
   7593                         appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
   7594                         if (!lastRef) {
   7595                             // This wasn't the last ref our process had on
   7596                             // the provider...  we have now been killed, bail.
   7597                             return null;
   7598                         }
   7599                         providerRunning = false;
   7600                         conn = null;
   7601                     }
   7602                 }
   7603 
   7604                 Binder.restoreCallingIdentity(origId);
   7605             }
   7606 
   7607             boolean singleton;
   7608             if (!providerRunning) {
   7609                 try {
   7610                     cpi = AppGlobals.getPackageManager().
   7611                         resolveContentProvider(name,
   7612                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
   7613                 } catch (RemoteException ex) {
   7614                 }
   7615                 if (cpi == null) {
   7616                     return null;
   7617                 }
   7618                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
   7619                         cpi.name, cpi.flags);
   7620                 if (singleton) {
   7621                     userId = 0;
   7622                 }
   7623                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
   7624 
   7625                 String msg;
   7626                 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
   7627                     throw new SecurityException(msg);
   7628                 }
   7629 
   7630                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
   7631                         && !cpi.processName.equals("system")) {
   7632                     // If this content provider does not run in the system
   7633                     // process, and the system is not yet ready to run other
   7634                     // processes, then fail fast instead of hanging.
   7635                     throw new IllegalArgumentException(
   7636                             "Attempt to launch content provider before system ready");
   7637                 }
   7638 
   7639                 // Make sure that the user who owns this provider is started.  If not,
   7640                 // we don't want to allow it to run.
   7641                 if (mStartedUsers.get(userId) == null) {
   7642                     Slog.w(TAG, "Unable to launch app "
   7643                             + cpi.applicationInfo.packageName + "/"
   7644                             + cpi.applicationInfo.uid + " for provider "
   7645                             + name + ": user " + userId + " is stopped");
   7646                     return null;
   7647                 }
   7648 
   7649                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
   7650                 cpr = mProviderMap.getProviderByClass(comp, userId);
   7651                 final boolean firstClass = cpr == null;
   7652                 if (firstClass) {
   7653                     try {
   7654                         ApplicationInfo ai =
   7655                             AppGlobals.getPackageManager().
   7656                                 getApplicationInfo(
   7657                                         cpi.applicationInfo.packageName,
   7658                                         STOCK_PM_FLAGS, userId);
   7659                         if (ai == null) {
   7660                             Slog.w(TAG, "No package info for content provider "
   7661                                     + cpi.name);
   7662                             return null;
   7663                         }
   7664                         ai = getAppInfoForUser(ai, userId);
   7665                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
   7666                     } catch (RemoteException ex) {
   7667                         // pm is in same process, this will never happen.
   7668                     }
   7669                 }
   7670 
   7671                 if (r != null && cpr.canRunHere(r)) {
   7672                     // If this is a multiprocess provider, then just return its
   7673                     // info and allow the caller to instantiate it.  Only do
   7674                     // this if the provider is the same user as the caller's
   7675                     // process, or can run as root (so can be in any process).
   7676                     return cpr.newHolder(null);
   7677                 }
   7678 
   7679                 if (DEBUG_PROVIDER) {
   7680                     RuntimeException e = new RuntimeException("here");
   7681                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
   7682                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
   7683                 }
   7684 
   7685                 // This is single process, and our app is now connecting to it.
   7686                 // See if we are already in the process of launching this
   7687                 // provider.
   7688                 final int N = mLaunchingProviders.size();
   7689                 int i;
   7690                 for (i=0; i<N; i++) {
   7691                     if (mLaunchingProviders.get(i) == cpr) {
   7692                         break;
   7693                     }
   7694                 }
   7695 
   7696                 // If the provider is not already being launched, then get it
   7697                 // started.
   7698                 if (i >= N) {
   7699                     final long origId = Binder.clearCallingIdentity();
   7700 
   7701                     try {
   7702                         // Content provider is now in use, its package can't be stopped.
   7703                         try {
   7704                             AppGlobals.getPackageManager().setPackageStoppedState(
   7705                                     cpr.appInfo.packageName, false, userId);
   7706                         } catch (RemoteException e) {
   7707                         } catch (IllegalArgumentException e) {
   7708                             Slog.w(TAG, "Failed trying to unstop package "
   7709                                     + cpr.appInfo.packageName + ": " + e);
   7710                         }
   7711 
   7712                         // Use existing process if already started
   7713                         ProcessRecord proc = getProcessRecordLocked(
   7714                                 cpi.processName, cpr.appInfo.uid, false);
   7715                         if (proc != null && proc.thread != null) {
   7716                             if (DEBUG_PROVIDER) {
   7717                                 Slog.d(TAG, "Installing in existing process " + proc);
   7718                             }
   7719                             proc.pubProviders.put(cpi.name, cpr);
   7720                             try {
   7721                                 proc.thread.scheduleInstallProvider(cpi);
   7722                             } catch (RemoteException e) {
   7723                             }
   7724                         } else {
   7725                             proc = startProcessLocked(cpi.processName,
   7726                                     cpr.appInfo, false, 0, "content provider",
   7727                                     new ComponentName(cpi.applicationInfo.packageName,
   7728                                             cpi.name), false, false, false);
   7729                             if (proc == null) {
   7730                                 Slog.w(TAG, "Unable to launch app "
   7731                                         + cpi.applicationInfo.packageName + "/"
   7732                                         + cpi.applicationInfo.uid + " for provider "
   7733                                         + name + ": process is bad");
   7734                                 return null;
   7735                             }
   7736                         }
   7737                         cpr.launchingApp = proc;
   7738                         mLaunchingProviders.add(cpr);
   7739                     } finally {
   7740                         Binder.restoreCallingIdentity(origId);
   7741                     }
   7742                 }
   7743 
   7744                 // Make sure the provider is published (the same provider class
   7745                 // may be published under multiple names).
   7746                 if (firstClass) {
   7747                     mProviderMap.putProviderByClass(comp, cpr);
   7748                 }
   7749 
   7750                 mProviderMap.putProviderByName(name, cpr);
   7751                 conn = incProviderCountLocked(r, cpr, token, stable);
   7752                 if (conn != null) {
   7753                     conn.waiting = true;
   7754                 }
   7755             }
   7756         }
   7757 
   7758         // Wait for the provider to be published...
   7759         synchronized (cpr) {
   7760             while (cpr.provider == null) {
   7761                 if (cpr.launchingApp == null) {
   7762                     Slog.w(TAG, "Unable to launch app "
   7763                             + cpi.applicationInfo.packageName + "/"
   7764                             + cpi.applicationInfo.uid + " for provider "
   7765                             + name + ": launching app became null");
   7766                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
   7767                             UserHandle.getUserId(cpi.applicationInfo.uid),
   7768                             cpi.applicationInfo.packageName,
   7769                             cpi.applicationInfo.uid, name);
   7770                     return null;
   7771                 }
   7772                 try {
   7773                     if (DEBUG_MU) {
   7774                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
   7775                                 + cpr.launchingApp);
   7776                     }
   7777                     if (conn != null) {
   7778                         conn.waiting = true;
   7779                     }
   7780                     cpr.wait();
   7781                 } catch (InterruptedException ex) {
   7782                 } finally {
   7783                     if (conn != null) {
   7784                         conn.waiting = false;
   7785                     }
   7786                 }
   7787             }
   7788         }
   7789         return cpr != null ? cpr.newHolder(conn) : null;
   7790     }
   7791 
   7792     public final ContentProviderHolder getContentProvider(
   7793             IApplicationThread caller, String name, int userId, boolean stable) {
   7794         enforceNotIsolatedCaller("getContentProvider");
   7795         if (caller == null) {
   7796             String msg = "null IApplicationThread when getting content provider "
   7797                     + name;
   7798             Slog.w(TAG, msg);
   7799             throw new SecurityException(msg);
   7800         }
   7801 
   7802         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   7803                 false, true, "getContentProvider", null);
   7804         return getContentProviderImpl(caller, name, null, stable, userId);
   7805     }
   7806 
   7807     public ContentProviderHolder getContentProviderExternal(
   7808             String name, int userId, IBinder token) {
   7809         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   7810             "Do not have permission in call getContentProviderExternal()");
   7811         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
   7812                 false, true, "getContentProvider", null);
   7813         return getContentProviderExternalUnchecked(name, token, userId);
   7814     }
   7815 
   7816     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
   7817             IBinder token, int userId) {
   7818         return getContentProviderImpl(null, name, token, true, userId);
   7819     }
   7820 
   7821     /**
   7822      * Drop a content provider from a ProcessRecord's bookkeeping
   7823      */
   7824     public void removeContentProvider(IBinder connection, boolean stable) {
   7825         enforceNotIsolatedCaller("removeContentProvider");
   7826         synchronized (this) {
   7827             ContentProviderConnection conn;
   7828             try {
   7829                 conn = (ContentProviderConnection)connection;
   7830             } catch (ClassCastException e) {
   7831                 String msg ="removeContentProvider: " + connection
   7832                         + " not a ContentProviderConnection";
   7833                 Slog.w(TAG, msg);
   7834                 throw new IllegalArgumentException(msg);
   7835             }
   7836             if (conn == null) {
   7837                 throw new NullPointerException("connection is null");
   7838             }
   7839             if (decProviderCountLocked(conn, null, null, stable)) {
   7840                 updateOomAdjLocked();
   7841             }
   7842         }
   7843     }
   7844 
   7845     public void removeContentProviderExternal(String name, IBinder token) {
   7846         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
   7847             "Do not have permission in call removeContentProviderExternal()");
   7848         removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
   7849     }
   7850 
   7851     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
   7852         synchronized (this) {
   7853             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
   7854             if(cpr == null) {
   7855                 //remove from mProvidersByClass
   7856                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
   7857                 return;
   7858             }
   7859 
   7860             //update content provider record entry info
   7861             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
   7862             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
   7863             if (localCpr.hasExternalProcessHandles()) {
   7864                 if (localCpr.removeExternalProcessHandleLocked(token)) {
   7865                     updateOomAdjLocked();
   7866                 } else {
   7867                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
   7868                             + " with no external reference for token: "
   7869                             + token + ".");
   7870                 }
   7871             } else {
   7872                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
   7873                         + " with no external references.");
   7874             }
   7875         }
   7876     }
   7877 
   7878     public final void publishContentProviders(IApplicationThread caller,
   7879             List<ContentProviderHolder> providers) {
   7880         if (providers == null) {
   7881             return;
   7882         }
   7883 
   7884         enforceNotIsolatedCaller("publishContentProviders");
   7885         synchronized (this) {
   7886             final ProcessRecord r = getRecordForAppLocked(caller);
   7887             if (DEBUG_MU)
   7888                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
   7889             if (r == null) {
   7890                 throw new SecurityException(
   7891                         "Unable to find app for caller " + caller
   7892                       + " (pid=" + Binder.getCallingPid()
   7893                       + ") when publishing content providers");
   7894             }
   7895 
   7896             final long origId = Binder.clearCallingIdentity();
   7897 
   7898             final int N = providers.size();
   7899             for (int i=0; i<N; i++) {
   7900                 ContentProviderHolder src = providers.get(i);
   7901                 if (src == null || src.info == null || src.provider == null) {
   7902                     continue;
   7903                 }
   7904                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
   7905                 if (DEBUG_MU)
   7906                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
   7907                 if (dst != null) {
   7908                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
   7909                     mProviderMap.putProviderByClass(comp, dst);
   7910                     String names[] = dst.info.authority.split(";");
   7911                     for (int j = 0; j < names.length; j++) {
   7912                         mProviderMap.putProviderByName(names[j], dst);
   7913                     }
   7914 
   7915                     int NL = mLaunchingProviders.size();
   7916                     int j;
   7917                     for (j=0; j<NL; j++) {
   7918                         if (mLaunchingProviders.get(j) == dst) {
   7919                             mLaunchingProviders.remove(j);
   7920                             j--;
   7921                             NL--;
   7922                         }
   7923                     }
   7924                     synchronized (dst) {
   7925                         dst.provider = src.provider;
   7926                         dst.proc = r;
   7927                         dst.notifyAll();
   7928                     }
   7929                     updateOomAdjLocked(r);
   7930                 }
   7931             }
   7932 
   7933             Binder.restoreCallingIdentity(origId);
   7934         }
   7935     }
   7936 
   7937     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
   7938         ContentProviderConnection conn;
   7939         try {
   7940             conn = (ContentProviderConnection)connection;
   7941         } catch (ClassCastException e) {
   7942             String msg ="refContentProvider: " + connection
   7943                     + " not a ContentProviderConnection";
   7944             Slog.w(TAG, msg);
   7945             throw new IllegalArgumentException(msg);
   7946         }
   7947         if (conn == null) {
   7948             throw new NullPointerException("connection is null");
   7949         }
   7950 
   7951         synchronized (this) {
   7952             if (stable > 0) {
   7953                 conn.numStableIncs += stable;
   7954             }
   7955             stable = conn.stableCount + stable;
   7956             if (stable < 0) {
   7957                 throw new IllegalStateException("stableCount < 0: " + stable);
   7958             }
   7959 
   7960             if (unstable > 0) {
   7961                 conn.numUnstableIncs += unstable;
   7962             }
   7963             unstable = conn.unstableCount + unstable;
   7964             if (unstable < 0) {
   7965                 throw new IllegalStateException("unstableCount < 0: " + unstable);
   7966             }
   7967 
   7968             if ((stable+unstable) <= 0) {
   7969                 throw new IllegalStateException("ref counts can't go to zero here: stable="
   7970                         + stable + " unstable=" + unstable);
   7971             }
   7972             conn.stableCount = stable;
   7973             conn.unstableCount = unstable;
   7974             return !conn.dead;
   7975         }
   7976     }
   7977 
   7978     public void unstableProviderDied(IBinder connection) {
   7979         ContentProviderConnection conn;
   7980         try {
   7981             conn = (ContentProviderConnection)connection;
   7982         } catch (ClassCastException e) {
   7983             String msg ="refContentProvider: " + connection
   7984                     + " not a ContentProviderConnection";
   7985             Slog.w(TAG, msg);
   7986             throw new IllegalArgumentException(msg);
   7987         }
   7988         if (conn == null) {
   7989             throw new NullPointerException("connection is null");
   7990         }
   7991 
   7992         // Safely retrieve the content provider associated with the connection.
   7993         IContentProvider provider;
   7994         synchronized (this) {
   7995             provider = conn.provider.provider;
   7996         }
   7997 
   7998         if (provider == null) {
   7999             // Um, yeah, we're way ahead of you.
   8000             return;
   8001         }
   8002 
   8003         // Make sure the caller is being honest with us.
   8004         if (provider.asBinder().pingBinder()) {
   8005             // Er, no, still looks good to us.
   8006             synchronized (this) {
   8007                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
   8008                         + " says " + conn + " died, but we don't agree");
   8009                 return;
   8010             }
   8011         }
   8012 
   8013         // Well look at that!  It's dead!
   8014         synchronized (this) {
   8015             if (conn.provider.provider != provider) {
   8016                 // But something changed...  good enough.
   8017                 return;
   8018             }
   8019 
   8020             ProcessRecord proc = conn.provider.proc;
   8021             if (proc == null || proc.thread == null) {
   8022                 // Seems like the process is already cleaned up.
   8023                 return;
   8024             }
   8025 
   8026             // As far as we're concerned, this is just like receiving a
   8027             // death notification...  just a bit prematurely.
   8028             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
   8029                     + ") early provider death");
   8030             final long ident = Binder.clearCallingIdentity();
   8031             try {
   8032                 appDiedLocked(proc, proc.pid, proc.thread);
   8033             } finally {
   8034                 Binder.restoreCallingIdentity(ident);
   8035             }
   8036         }
   8037     }
   8038 
   8039     @Override
   8040     public void appNotRespondingViaProvider(IBinder connection) {
   8041         enforceCallingPermission(
   8042                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
   8043 
   8044         final ContentProviderConnection conn = (ContentProviderConnection) connection;
   8045         if (conn == null) {
   8046             Slog.w(TAG, "ContentProviderConnection is null");
   8047             return;
   8048         }
   8049 
   8050         final ProcessRecord host = conn.provider.proc;
   8051         if (host == null) {
   8052             Slog.w(TAG, "Failed to find hosting ProcessRecord");
   8053             return;
   8054         }
   8055 
   8056         final long token = Binder.clearCallingIdentity();
   8057         try {
   8058             appNotResponding(host, null, null, false, "ContentProvider not responding");
   8059         } finally {
   8060             Binder.restoreCallingIdentity(token);
   8061         }
   8062     }
   8063 
   8064     public static final void installSystemProviders() {
   8065         List<ProviderInfo> providers;
   8066         synchronized (mSelf) {
   8067             ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
   8068             providers = mSelf.generateApplicationProvidersLocked(app);
   8069             if (providers != null) {
   8070                 for (int i=providers.size()-1; i>=0; i--) {
   8071                     ProviderInfo pi = (ProviderInfo)providers.get(i);
   8072                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   8073                         Slog.w(TAG, "Not installing system proc provider " + pi.name
   8074                                 + ": not system .apk");
   8075                         providers.remove(i);
   8076                     }
   8077                 }
   8078             }
   8079         }
   8080         if (providers != null) {
   8081             mSystemThread.installSystemProviders(providers);
   8082         }
   8083 
   8084         mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
   8085 
   8086         mSelf.mUsageStatsService.monitorPackages();
   8087     }
   8088 
   8089     /**
   8090      * Allows app to retrieve the MIME type of a URI without having permission
   8091      * to access its content provider.
   8092      *
   8093      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
   8094      *
   8095      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
   8096      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
   8097      */
   8098     public String getProviderMimeType(Uri uri, int userId) {
   8099         enforceNotIsolatedCaller("getProviderMimeType");
   8100         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   8101                 userId, false, true, "getProviderMimeType", null);
   8102         final String name = uri.getAuthority();
   8103         final long ident = Binder.clearCallingIdentity();
   8104         ContentProviderHolder holder = null;
   8105 
   8106         try {
   8107             holder = getContentProviderExternalUnchecked(name, null, userId);
   8108             if (holder != null) {
   8109                 return holder.provider.getType(uri);
   8110             }
   8111         } catch (RemoteException e) {
   8112             Log.w(TAG, "Content provider dead retrieving " + uri, e);
   8113             return null;
   8114         } finally {
   8115             if (holder != null) {
   8116                 removeContentProviderExternalUnchecked(name, null, userId);
   8117             }
   8118             Binder.restoreCallingIdentity(ident);
   8119         }
   8120 
   8121         return null;
   8122     }
   8123 
   8124     // =========================================================
   8125     // GLOBAL MANAGEMENT
   8126     // =========================================================
   8127 
   8128     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
   8129             boolean isolated) {
   8130         String proc = customProcess != null ? customProcess : info.processName;
   8131         BatteryStatsImpl.Uid.Proc ps = null;
   8132         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8133         int uid = info.uid;
   8134         if (isolated) {
   8135             int userId = UserHandle.getUserId(uid);
   8136             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
   8137             while (true) {
   8138                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
   8139                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
   8140                     mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
   8141                 }
   8142                 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
   8143                 mNextIsolatedProcessUid++;
   8144                 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
   8145                     // No process for this uid, use it.
   8146                     break;
   8147                 }
   8148                 stepsLeft--;
   8149                 if (stepsLeft <= 0) {
   8150                     return null;
   8151                 }
   8152             }
   8153         }
   8154         return new ProcessRecord(stats, info, proc, uid);
   8155     }
   8156 
   8157     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
   8158         ProcessRecord app;
   8159         if (!isolated) {
   8160             app = getProcessRecordLocked(info.processName, info.uid, true);
   8161         } else {
   8162             app = null;
   8163         }
   8164 
   8165         if (app == null) {
   8166             app = newProcessRecordLocked(info, null, isolated);
   8167             mProcessNames.put(info.processName, app.uid, app);
   8168             if (isolated) {
   8169                 mIsolatedProcesses.put(app.uid, app);
   8170             }
   8171             updateLruProcessLocked(app, false, null);
   8172             updateOomAdjLocked();
   8173         }
   8174 
   8175         // This package really, really can not be stopped.
   8176         try {
   8177             AppGlobals.getPackageManager().setPackageStoppedState(
   8178                     info.packageName, false, UserHandle.getUserId(app.uid));
   8179         } catch (RemoteException e) {
   8180         } catch (IllegalArgumentException e) {
   8181             Slog.w(TAG, "Failed trying to unstop package "
   8182                     + info.packageName + ": " + e);
   8183         }
   8184 
   8185         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
   8186                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
   8187             app.persistent = true;
   8188             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
   8189         }
   8190         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
   8191             mPersistentStartingProcesses.add(app);
   8192             startProcessLocked(app, "added application", app.processName);
   8193         }
   8194 
   8195         return app;
   8196     }
   8197 
   8198     public void unhandledBack() {
   8199         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
   8200                 "unhandledBack()");
   8201 
   8202         synchronized(this) {
   8203             final long origId = Binder.clearCallingIdentity();
   8204             try {
   8205                 getFocusedStack().unhandledBackLocked();
   8206             } finally {
   8207                 Binder.restoreCallingIdentity(origId);
   8208             }
   8209         }
   8210     }
   8211 
   8212     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
   8213         enforceNotIsolatedCaller("openContentUri");
   8214         final int userId = UserHandle.getCallingUserId();
   8215         String name = uri.getAuthority();
   8216         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
   8217         ParcelFileDescriptor pfd = null;
   8218         if (cph != null) {
   8219             // We record the binder invoker's uid in thread-local storage before
   8220             // going to the content provider to open the file.  Later, in the code
   8221             // that handles all permissions checks, we look for this uid and use
   8222             // that rather than the Activity Manager's own uid.  The effect is that
   8223             // we do the check against the caller's permissions even though it looks
   8224             // to the content provider like the Activity Manager itself is making
   8225             // the request.
   8226             sCallerIdentity.set(new Identity(
   8227                     Binder.getCallingPid(), Binder.getCallingUid()));
   8228             try {
   8229                 pfd = cph.provider.openFile(null, uri, "r", null);
   8230             } catch (FileNotFoundException e) {
   8231                 // do nothing; pfd will be returned null
   8232             } finally {
   8233                 // Ensure that whatever happens, we clean up the identity state
   8234                 sCallerIdentity.remove();
   8235             }
   8236 
   8237             // We've got the fd now, so we're done with the provider.
   8238             removeContentProviderExternalUnchecked(name, null, userId);
   8239         } else {
   8240             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
   8241         }
   8242         return pfd;
   8243     }
   8244 
   8245     // Actually is sleeping or shutting down or whatever else in the future
   8246     // is an inactive state.
   8247     public boolean isSleepingOrShuttingDown() {
   8248         return mSleeping || mShuttingDown;
   8249     }
   8250 
   8251     public void goingToSleep() {
   8252         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8253                 != PackageManager.PERMISSION_GRANTED) {
   8254             throw new SecurityException("Requires permission "
   8255                     + android.Manifest.permission.DEVICE_POWER);
   8256         }
   8257 
   8258         synchronized(this) {
   8259             mWentToSleep = true;
   8260             updateEventDispatchingLocked();
   8261 
   8262             if (!mSleeping) {
   8263                 mSleeping = true;
   8264                 mStackSupervisor.goingToSleepLocked();
   8265 
   8266                 // Initialize the wake times of all processes.
   8267                 checkExcessivePowerUsageLocked(false);
   8268                 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   8269                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
   8270                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
   8271             }
   8272         }
   8273     }
   8274 
   8275     @Override
   8276     public boolean shutdown(int timeout) {
   8277         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
   8278                 != PackageManager.PERMISSION_GRANTED) {
   8279             throw new SecurityException("Requires permission "
   8280                     + android.Manifest.permission.SHUTDOWN);
   8281         }
   8282 
   8283         boolean timedout = false;
   8284 
   8285         synchronized(this) {
   8286             mShuttingDown = true;
   8287             updateEventDispatchingLocked();
   8288             timedout = mStackSupervisor.shutdownLocked(timeout);
   8289         }
   8290 
   8291         mAppOpsService.shutdown();
   8292         mUsageStatsService.shutdown();
   8293         mBatteryStatsService.shutdown();
   8294         synchronized (this) {
   8295             mProcessStats.shutdownLocked();
   8296         }
   8297 
   8298         return timedout;
   8299     }
   8300 
   8301     public final void activitySlept(IBinder token) {
   8302         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
   8303 
   8304         final long origId = Binder.clearCallingIdentity();
   8305 
   8306         synchronized (this) {
   8307             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8308             if (r != null) {
   8309                 mStackSupervisor.activitySleptLocked(r);
   8310             }
   8311         }
   8312 
   8313         Binder.restoreCallingIdentity(origId);
   8314     }
   8315 
   8316     void logLockScreen(String msg) {
   8317         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
   8318                 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
   8319                 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
   8320                 mStackSupervisor.mDismissKeyguardOnNextActivity);
   8321     }
   8322 
   8323     private void comeOutOfSleepIfNeededLocked() {
   8324         if (!mWentToSleep && !mLockScreenShown) {
   8325             if (mSleeping) {
   8326                 mSleeping = false;
   8327                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
   8328             }
   8329         }
   8330     }
   8331 
   8332     public void wakingUp() {
   8333         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8334                 != PackageManager.PERMISSION_GRANTED) {
   8335             throw new SecurityException("Requires permission "
   8336                     + android.Manifest.permission.DEVICE_POWER);
   8337         }
   8338 
   8339         synchronized(this) {
   8340             mWentToSleep = false;
   8341             updateEventDispatchingLocked();
   8342             comeOutOfSleepIfNeededLocked();
   8343         }
   8344     }
   8345 
   8346     private void updateEventDispatchingLocked() {
   8347         mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
   8348     }
   8349 
   8350     public void setLockScreenShown(boolean shown) {
   8351         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
   8352                 != PackageManager.PERMISSION_GRANTED) {
   8353             throw new SecurityException("Requires permission "
   8354                     + android.Manifest.permission.DEVICE_POWER);
   8355         }
   8356 
   8357         synchronized(this) {
   8358             long ident = Binder.clearCallingIdentity();
   8359             try {
   8360                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
   8361                 mLockScreenShown = shown;
   8362                 comeOutOfSleepIfNeededLocked();
   8363             } finally {
   8364                 Binder.restoreCallingIdentity(ident);
   8365             }
   8366         }
   8367     }
   8368 
   8369     public void stopAppSwitches() {
   8370         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8371                 != PackageManager.PERMISSION_GRANTED) {
   8372             throw new SecurityException("Requires permission "
   8373                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8374         }
   8375 
   8376         synchronized(this) {
   8377             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
   8378                     + APP_SWITCH_DELAY_TIME;
   8379             mDidAppSwitch = false;
   8380             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8381             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
   8382             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
   8383         }
   8384     }
   8385 
   8386     public void resumeAppSwitches() {
   8387         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
   8388                 != PackageManager.PERMISSION_GRANTED) {
   8389             throw new SecurityException("Requires permission "
   8390                     + android.Manifest.permission.STOP_APP_SWITCHES);
   8391         }
   8392 
   8393         synchronized(this) {
   8394             // Note that we don't execute any pending app switches... we will
   8395             // let those wait until either the timeout, or the next start
   8396             // activity request.
   8397             mAppSwitchesAllowedTime = 0;
   8398         }
   8399     }
   8400 
   8401     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
   8402             String name) {
   8403         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
   8404             return true;
   8405         }
   8406 
   8407         final int perm = checkComponentPermission(
   8408                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
   8409                 callingUid, -1, true);
   8410         if (perm == PackageManager.PERMISSION_GRANTED) {
   8411             return true;
   8412         }
   8413 
   8414         Slog.w(TAG, name + " request from " + callingUid + " stopped");
   8415         return false;
   8416     }
   8417 
   8418     public void setDebugApp(String packageName, boolean waitForDebugger,
   8419             boolean persistent) {
   8420         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
   8421                 "setDebugApp()");
   8422 
   8423         long ident = Binder.clearCallingIdentity();
   8424         try {
   8425             // Note that this is not really thread safe if there are multiple
   8426             // callers into it at the same time, but that's not a situation we
   8427             // care about.
   8428             if (persistent) {
   8429                 final ContentResolver resolver = mContext.getContentResolver();
   8430                 Settings.Global.putString(
   8431                     resolver, Settings.Global.DEBUG_APP,
   8432                     packageName);
   8433                 Settings.Global.putInt(
   8434                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
   8435                     waitForDebugger ? 1 : 0);
   8436             }
   8437 
   8438             synchronized (this) {
   8439                 if (!persistent) {
   8440                     mOrigDebugApp = mDebugApp;
   8441                     mOrigWaitForDebugger = mWaitForDebugger;
   8442                 }
   8443                 mDebugApp = packageName;
   8444                 mWaitForDebugger = waitForDebugger;
   8445                 mDebugTransient = !persistent;
   8446                 if (packageName != null) {
   8447                     forceStopPackageLocked(packageName, -1, false, false, true, true,
   8448                             false, UserHandle.USER_ALL, "set debug app");
   8449                 }
   8450             }
   8451         } finally {
   8452             Binder.restoreCallingIdentity(ident);
   8453         }
   8454     }
   8455 
   8456     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
   8457         synchronized (this) {
   8458             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   8459             if (!isDebuggable) {
   8460                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   8461                     throw new SecurityException("Process not debuggable: " + app.packageName);
   8462                 }
   8463             }
   8464 
   8465             mOpenGlTraceApp = processName;
   8466         }
   8467     }
   8468 
   8469     void setProfileApp(ApplicationInfo app, String processName, String profileFile,
   8470             ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
   8471         synchronized (this) {
   8472             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   8473             if (!isDebuggable) {
   8474                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   8475                     throw new SecurityException("Process not debuggable: " + app.packageName);
   8476                 }
   8477             }
   8478             mProfileApp = processName;
   8479             mProfileFile = profileFile;
   8480             if (mProfileFd != null) {
   8481                 try {
   8482                     mProfileFd.close();
   8483                 } catch (IOException e) {
   8484                 }
   8485                 mProfileFd = null;
   8486             }
   8487             mProfileFd = profileFd;
   8488             mProfileType = 0;
   8489             mAutoStopProfiler = autoStopProfiler;
   8490         }
   8491     }
   8492 
   8493     @Override
   8494     public void setAlwaysFinish(boolean enabled) {
   8495         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
   8496                 "setAlwaysFinish()");
   8497 
   8498         Settings.Global.putInt(
   8499                 mContext.getContentResolver(),
   8500                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
   8501 
   8502         synchronized (this) {
   8503             mAlwaysFinishActivities = enabled;
   8504         }
   8505     }
   8506 
   8507     @Override
   8508     public void setActivityController(IActivityController controller) {
   8509         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   8510                 "setActivityController()");
   8511         synchronized (this) {
   8512             mController = controller;
   8513             Watchdog.getInstance().setActivityController(controller);
   8514         }
   8515     }
   8516 
   8517     @Override
   8518     public void setUserIsMonkey(boolean userIsMonkey) {
   8519         synchronized (this) {
   8520             synchronized (mPidsSelfLocked) {
   8521                 final int callingPid = Binder.getCallingPid();
   8522                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
   8523                 if (precessRecord == null) {
   8524                     throw new SecurityException("Unknown process: " + callingPid);
   8525                 }
   8526                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
   8527                     throw new SecurityException("Only an instrumentation process "
   8528                             + "with a UiAutomation can call setUserIsMonkey");
   8529                 }
   8530             }
   8531             mUserIsMonkey = userIsMonkey;
   8532         }
   8533     }
   8534 
   8535     @Override
   8536     public boolean isUserAMonkey() {
   8537         synchronized (this) {
   8538             // If there is a controller also implies the user is a monkey.
   8539             return (mUserIsMonkey || mController != null);
   8540         }
   8541     }
   8542 
   8543     public void requestBugReport() {
   8544         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
   8545         SystemProperties.set("ctl.start", "bugreport");
   8546     }
   8547 
   8548     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
   8549         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
   8550     }
   8551 
   8552     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
   8553         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
   8554             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
   8555         }
   8556         return KEY_DISPATCHING_TIMEOUT;
   8557     }
   8558 
   8559     @Override
   8560     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
   8561         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   8562                 != PackageManager.PERMISSION_GRANTED) {
   8563             throw new SecurityException("Requires permission "
   8564                     + android.Manifest.permission.FILTER_EVENTS);
   8565         }
   8566         ProcessRecord proc;
   8567         long timeout;
   8568         synchronized (this) {
   8569             synchronized (mPidsSelfLocked) {
   8570                 proc = mPidsSelfLocked.get(pid);
   8571             }
   8572             timeout = getInputDispatchingTimeoutLocked(proc);
   8573         }
   8574 
   8575         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
   8576             return -1;
   8577         }
   8578 
   8579         return timeout;
   8580     }
   8581 
   8582     /**
   8583      * Handle input dispatching timeouts.
   8584      * Returns whether input dispatching should be aborted or not.
   8585      */
   8586     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
   8587             final ActivityRecord activity, final ActivityRecord parent,
   8588             final boolean aboveSystem, String reason) {
   8589         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
   8590                 != PackageManager.PERMISSION_GRANTED) {
   8591             throw new SecurityException("Requires permission "
   8592                     + android.Manifest.permission.FILTER_EVENTS);
   8593         }
   8594 
   8595         final String annotation;
   8596         if (reason == null) {
   8597             annotation = "Input dispatching timed out";
   8598         } else {
   8599             annotation = "Input dispatching timed out (" + reason + ")";
   8600         }
   8601 
   8602         if (proc != null) {
   8603             synchronized (this) {
   8604                 if (proc.debugging) {
   8605                     return false;
   8606                 }
   8607 
   8608                 if (mDidDexOpt) {
   8609                     // Give more time since we were dexopting.
   8610                     mDidDexOpt = false;
   8611                     return false;
   8612                 }
   8613 
   8614                 if (proc.instrumentationClass != null) {
   8615                     Bundle info = new Bundle();
   8616                     info.putString("shortMsg", "keyDispatchingTimedOut");
   8617                     info.putString("longMsg", annotation);
   8618                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
   8619                     return true;
   8620                 }
   8621             }
   8622             mHandler.post(new Runnable() {
   8623                 @Override
   8624                 public void run() {
   8625                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
   8626                 }
   8627             });
   8628         }
   8629 
   8630         return true;
   8631     }
   8632 
   8633     public Bundle getAssistContextExtras(int requestType) {
   8634         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
   8635                 "getAssistContextExtras()");
   8636         PendingAssistExtras pae;
   8637         Bundle extras = new Bundle();
   8638         synchronized (this) {
   8639             ActivityRecord activity = getFocusedStack().mResumedActivity;
   8640             if (activity == null) {
   8641                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
   8642                 return null;
   8643             }
   8644             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
   8645             if (activity.app == null || activity.app.thread == null) {
   8646                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
   8647                 return extras;
   8648             }
   8649             if (activity.app.pid == Binder.getCallingPid()) {
   8650                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
   8651                 return extras;
   8652             }
   8653             pae = new PendingAssistExtras(activity);
   8654             try {
   8655                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
   8656                         requestType);
   8657                 mPendingAssistExtras.add(pae);
   8658                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
   8659             } catch (RemoteException e) {
   8660                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
   8661                 return extras;
   8662             }
   8663         }
   8664         synchronized (pae) {
   8665             while (!pae.haveResult) {
   8666                 try {
   8667                     pae.wait();
   8668                 } catch (InterruptedException e) {
   8669                 }
   8670             }
   8671             if (pae.result != null) {
   8672                 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
   8673             }
   8674         }
   8675         synchronized (this) {
   8676             mPendingAssistExtras.remove(pae);
   8677             mHandler.removeCallbacks(pae);
   8678         }
   8679         return extras;
   8680     }
   8681 
   8682     public void reportAssistContextExtras(IBinder token, Bundle extras) {
   8683         PendingAssistExtras pae = (PendingAssistExtras)token;
   8684         synchronized (pae) {
   8685             pae.result = extras;
   8686             pae.haveResult = true;
   8687             pae.notifyAll();
   8688         }
   8689     }
   8690 
   8691     public void registerProcessObserver(IProcessObserver observer) {
   8692         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
   8693                 "registerProcessObserver()");
   8694         synchronized (this) {
   8695             mProcessObservers.register(observer);
   8696         }
   8697     }
   8698 
   8699     @Override
   8700     public void unregisterProcessObserver(IProcessObserver observer) {
   8701         synchronized (this) {
   8702             mProcessObservers.unregister(observer);
   8703         }
   8704     }
   8705 
   8706     @Override
   8707     public boolean convertFromTranslucent(IBinder token) {
   8708         final long origId = Binder.clearCallingIdentity();
   8709         try {
   8710             synchronized (this) {
   8711                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8712                 if (r == null) {
   8713                     return false;
   8714                 }
   8715                 if (r.changeWindowTranslucency(true)) {
   8716                     mWindowManager.setAppFullscreen(token, true);
   8717                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   8718                     return true;
   8719                 }
   8720                 return false;
   8721             }
   8722         } finally {
   8723             Binder.restoreCallingIdentity(origId);
   8724         }
   8725     }
   8726 
   8727     @Override
   8728     public boolean convertToTranslucent(IBinder token) {
   8729         final long origId = Binder.clearCallingIdentity();
   8730         try {
   8731             synchronized (this) {
   8732                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8733                 if (r == null) {
   8734                     return false;
   8735                 }
   8736                 if (r.changeWindowTranslucency(false)) {
   8737                     r.task.stack.convertToTranslucent(r);
   8738                     mWindowManager.setAppFullscreen(token, false);
   8739                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
   8740                     return true;
   8741                 }
   8742                 return false;
   8743             }
   8744         } finally {
   8745             Binder.restoreCallingIdentity(origId);
   8746         }
   8747     }
   8748 
   8749     @Override
   8750     public void setImmersive(IBinder token, boolean immersive) {
   8751         synchronized(this) {
   8752             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8753             if (r == null) {
   8754                 throw new IllegalArgumentException();
   8755             }
   8756             r.immersive = immersive;
   8757 
   8758             // update associated state if we're frontmost
   8759             if (r == mFocusedActivity) {
   8760                 if (DEBUG_IMMERSIVE) {
   8761                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
   8762                 }
   8763                 applyUpdateLockStateLocked(r);
   8764             }
   8765         }
   8766     }
   8767 
   8768     @Override
   8769     public boolean isImmersive(IBinder token) {
   8770         synchronized (this) {
   8771             ActivityRecord r = ActivityRecord.isInStackLocked(token);
   8772             if (r == null) {
   8773                 throw new IllegalArgumentException();
   8774             }
   8775             return r.immersive;
   8776         }
   8777     }
   8778 
   8779     public boolean isTopActivityImmersive() {
   8780         enforceNotIsolatedCaller("startActivity");
   8781         synchronized (this) {
   8782             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
   8783             return (r != null) ? r.immersive : false;
   8784         }
   8785     }
   8786 
   8787     public final void enterSafeMode() {
   8788         synchronized(this) {
   8789             // It only makes sense to do this before the system is ready
   8790             // and started launching other packages.
   8791             if (!mSystemReady) {
   8792                 try {
   8793                     AppGlobals.getPackageManager().enterSafeMode();
   8794                 } catch (RemoteException e) {
   8795                 }
   8796             }
   8797         }
   8798     }
   8799 
   8800     public final void showSafeModeOverlay() {
   8801         View v = LayoutInflater.from(mContext).inflate(
   8802                 com.android.internal.R.layout.safe_mode, null);
   8803         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
   8804         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
   8805         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
   8806         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
   8807         lp.gravity = Gravity.BOTTOM | Gravity.START;
   8808         lp.format = v.getBackground().getOpacity();
   8809         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
   8810                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
   8811         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
   8812         ((WindowManager)mContext.getSystemService(
   8813                 Context.WINDOW_SERVICE)).addView(v, lp);
   8814     }
   8815 
   8816     public void noteWakeupAlarm(IIntentSender sender) {
   8817         if (!(sender instanceof PendingIntentRecord)) {
   8818             return;
   8819         }
   8820         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   8821         synchronized (stats) {
   8822             if (mBatteryStatsService.isOnBattery()) {
   8823                 mBatteryStatsService.enforceCallingPermission();
   8824                 PendingIntentRecord rec = (PendingIntentRecord)sender;
   8825                 int MY_UID = Binder.getCallingUid();
   8826                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
   8827                 BatteryStatsImpl.Uid.Pkg pkg =
   8828                     stats.getPackageStatsLocked(uid, rec.key.packageName);
   8829                 pkg.incWakeupsLocked();
   8830             }
   8831         }
   8832     }
   8833 
   8834     public boolean killPids(int[] pids, String pReason, boolean secure) {
   8835         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8836             throw new SecurityException("killPids only available to the system");
   8837         }
   8838         String reason = (pReason == null) ? "Unknown" : pReason;
   8839         // XXX Note: don't acquire main activity lock here, because the window
   8840         // manager calls in with its locks held.
   8841 
   8842         boolean killed = false;
   8843         synchronized (mPidsSelfLocked) {
   8844             int[] types = new int[pids.length];
   8845             int worstType = 0;
   8846             for (int i=0; i<pids.length; i++) {
   8847                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8848                 if (proc != null) {
   8849                     int type = proc.setAdj;
   8850                     types[i] = type;
   8851                     if (type > worstType) {
   8852                         worstType = type;
   8853                     }
   8854                 }
   8855             }
   8856 
   8857             // If the worst oom_adj is somewhere in the cached proc LRU range,
   8858             // then constrain it so we will kill all cached procs.
   8859             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
   8860                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
   8861                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
   8862             }
   8863 
   8864             // If this is not a secure call, don't let it kill processes that
   8865             // are important.
   8866             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
   8867                 worstType = ProcessList.SERVICE_ADJ;
   8868             }
   8869 
   8870             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
   8871             for (int i=0; i<pids.length; i++) {
   8872                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
   8873                 if (proc == null) {
   8874                     continue;
   8875                 }
   8876                 int adj = proc.setAdj;
   8877                 if (adj >= worstType && !proc.killedByAm) {
   8878                     killUnneededProcessLocked(proc, reason);
   8879                     killed = true;
   8880                 }
   8881             }
   8882         }
   8883         return killed;
   8884     }
   8885 
   8886     @Override
   8887     public void killUid(int uid, String reason) {
   8888         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8889             throw new SecurityException("killUid only available to the system");
   8890         }
   8891         synchronized (this) {
   8892             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
   8893                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
   8894                     reason != null ? reason : "kill uid");
   8895         }
   8896     }
   8897 
   8898     @Override
   8899     public boolean killProcessesBelowForeground(String reason) {
   8900         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8901             throw new SecurityException("killProcessesBelowForeground() only available to system");
   8902         }
   8903 
   8904         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
   8905     }
   8906 
   8907     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
   8908         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   8909             throw new SecurityException("killProcessesBelowAdj() only available to system");
   8910         }
   8911 
   8912         boolean killed = false;
   8913         synchronized (mPidsSelfLocked) {
   8914             final int size = mPidsSelfLocked.size();
   8915             for (int i = 0; i < size; i++) {
   8916                 final int pid = mPidsSelfLocked.keyAt(i);
   8917                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   8918                 if (proc == null) continue;
   8919 
   8920                 final int adj = proc.setAdj;
   8921                 if (adj > belowAdj && !proc.killedByAm) {
   8922                     killUnneededProcessLocked(proc, reason);
   8923                     killed = true;
   8924                 }
   8925             }
   8926         }
   8927         return killed;
   8928     }
   8929 
   8930     @Override
   8931     public void hang(final IBinder who, boolean allowRestart) {
   8932         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   8933                 != PackageManager.PERMISSION_GRANTED) {
   8934             throw new SecurityException("Requires permission "
   8935                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   8936         }
   8937 
   8938         final IBinder.DeathRecipient death = new DeathRecipient() {
   8939             @Override
   8940             public void binderDied() {
   8941                 synchronized (this) {
   8942                     notifyAll();
   8943                 }
   8944             }
   8945         };
   8946 
   8947         try {
   8948             who.linkToDeath(death, 0);
   8949         } catch (RemoteException e) {
   8950             Slog.w(TAG, "hang: given caller IBinder is already dead.");
   8951             return;
   8952         }
   8953 
   8954         synchronized (this) {
   8955             Watchdog.getInstance().setAllowRestart(allowRestart);
   8956             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
   8957             synchronized (death) {
   8958                 while (who.isBinderAlive()) {
   8959                     try {
   8960                         death.wait();
   8961                     } catch (InterruptedException e) {
   8962                     }
   8963                 }
   8964             }
   8965             Watchdog.getInstance().setAllowRestart(true);
   8966         }
   8967     }
   8968 
   8969     @Override
   8970     public void restart() {
   8971         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   8972                 != PackageManager.PERMISSION_GRANTED) {
   8973             throw new SecurityException("Requires permission "
   8974                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   8975         }
   8976 
   8977         Log.i(TAG, "Sending shutdown broadcast...");
   8978 
   8979         BroadcastReceiver br = new BroadcastReceiver() {
   8980             @Override public void onReceive(Context context, Intent intent) {
   8981                 // Now the broadcast is done, finish up the low-level shutdown.
   8982                 Log.i(TAG, "Shutting down activity manager...");
   8983                 shutdown(10000);
   8984                 Log.i(TAG, "Shutdown complete, restarting!");
   8985                 Process.killProcess(Process.myPid());
   8986                 System.exit(10);
   8987             }
   8988         };
   8989 
   8990         // First send the high-level shut down broadcast.
   8991         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
   8992         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   8993         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   8994         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
   8995         mContext.sendOrderedBroadcastAsUser(intent,
   8996                 UserHandle.ALL, null, br, mHandler, 0, null, null);
   8997         */
   8998         br.onReceive(mContext, intent);
   8999     }
   9000 
   9001     private long getLowRamTimeSinceIdle(long now) {
   9002         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
   9003     }
   9004 
   9005     @Override
   9006     public void performIdleMaintenance() {
   9007         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   9008                 != PackageManager.PERMISSION_GRANTED) {
   9009             throw new SecurityException("Requires permission "
   9010                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   9011         }
   9012 
   9013         synchronized (this) {
   9014             final long now = SystemClock.uptimeMillis();
   9015             final long timeSinceLastIdle = now - mLastIdleTime;
   9016             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
   9017             mLastIdleTime = now;
   9018             mLowRamTimeSinceLastIdle = 0;
   9019             if (mLowRamStartTime != 0) {
   9020                 mLowRamStartTime = now;
   9021             }
   9022 
   9023             StringBuilder sb = new StringBuilder(128);
   9024             sb.append("Idle maintenance over ");
   9025             TimeUtils.formatDuration(timeSinceLastIdle, sb);
   9026             sb.append(" low RAM for ");
   9027             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
   9028             Slog.i(TAG, sb.toString());
   9029 
   9030             // If at least 1/3 of our time since the last idle period has been spent
   9031             // with RAM low, then we want to kill processes.
   9032             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
   9033 
   9034             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   9035                 ProcessRecord proc = mLruProcesses.get(i);
   9036                 if (proc.notCachedSinceIdle) {
   9037                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
   9038                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
   9039                         if (doKilling && proc.initialIdlePss != 0
   9040                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
   9041                             killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
   9042                                     + " from " + proc.initialIdlePss + ")");
   9043                         }
   9044                     }
   9045                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
   9046                     proc.notCachedSinceIdle = true;
   9047                     proc.initialIdlePss = 0;
   9048                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
   9049                             mSleeping, now);
   9050                 }
   9051             }
   9052 
   9053             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
   9054             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
   9055         }
   9056     }
   9057 
   9058     public final void startRunning(String pkg, String cls, String action,
   9059             String data) {
   9060         synchronized(this) {
   9061             if (mStartRunning) {
   9062                 return;
   9063             }
   9064             mStartRunning = true;
   9065             mTopComponent = pkg != null && cls != null
   9066                     ? new ComponentName(pkg, cls) : null;
   9067             mTopAction = action != null ? action : Intent.ACTION_MAIN;
   9068             mTopData = data;
   9069             if (!mSystemReady) {
   9070                 return;
   9071             }
   9072         }
   9073 
   9074         systemReady(null);
   9075     }
   9076 
   9077     private void retrieveSettings() {
   9078         final ContentResolver resolver = mContext.getContentResolver();
   9079         String debugApp = Settings.Global.getString(
   9080             resolver, Settings.Global.DEBUG_APP);
   9081         boolean waitForDebugger = Settings.Global.getInt(
   9082             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
   9083         boolean alwaysFinishActivities = Settings.Global.getInt(
   9084             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
   9085         boolean forceRtl = Settings.Global.getInt(
   9086                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
   9087         // Transfer any global setting for forcing RTL layout, into a System Property
   9088         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
   9089 
   9090         Configuration configuration = new Configuration();
   9091         Settings.System.getConfiguration(resolver, configuration);
   9092         if (forceRtl) {
   9093             // This will take care of setting the correct layout direction flags
   9094             configuration.setLayoutDirection(configuration.locale);
   9095         }
   9096 
   9097         synchronized (this) {
   9098             mDebugApp = mOrigDebugApp = debugApp;
   9099             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
   9100             mAlwaysFinishActivities = alwaysFinishActivities;
   9101             // This happens before any activities are started, so we can
   9102             // change mConfiguration in-place.
   9103             updateConfigurationLocked(configuration, null, false, true);
   9104             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
   9105         }
   9106     }
   9107 
   9108     public boolean testIsSystemReady() {
   9109         // no need to synchronize(this) just to read & return the value
   9110         return mSystemReady;
   9111     }
   9112 
   9113     private static File getCalledPreBootReceiversFile() {
   9114         File dataDir = Environment.getDataDirectory();
   9115         File systemDir = new File(dataDir, "system");
   9116         File fname = new File(systemDir, "called_pre_boots.dat");
   9117         return fname;
   9118     }
   9119 
   9120     static final int LAST_DONE_VERSION = 10000;
   9121 
   9122     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
   9123         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
   9124         File file = getCalledPreBootReceiversFile();
   9125         FileInputStream fis = null;
   9126         try {
   9127             fis = new FileInputStream(file);
   9128             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
   9129             int fvers = dis.readInt();
   9130             if (fvers == LAST_DONE_VERSION) {
   9131                 String vers = dis.readUTF();
   9132                 String codename = dis.readUTF();
   9133                 String build = dis.readUTF();
   9134                 if (android.os.Build.VERSION.RELEASE.equals(vers)
   9135                         && android.os.Build.VERSION.CODENAME.equals(codename)
   9136                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
   9137                     int num = dis.readInt();
   9138                     while (num > 0) {
   9139                         num--;
   9140                         String pkg = dis.readUTF();
   9141                         String cls = dis.readUTF();
   9142                         lastDoneReceivers.add(new ComponentName(pkg, cls));
   9143                     }
   9144                 }
   9145             }
   9146         } catch (FileNotFoundException e) {
   9147         } catch (IOException e) {
   9148             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
   9149         } finally {
   9150             if (fis != null) {
   9151                 try {
   9152                     fis.close();
   9153                 } catch (IOException e) {
   9154                 }
   9155             }
   9156         }
   9157         return lastDoneReceivers;
   9158     }
   9159 
   9160     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
   9161         File file = getCalledPreBootReceiversFile();
   9162         FileOutputStream fos = null;
   9163         DataOutputStream dos = null;
   9164         try {
   9165             Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
   9166             fos = new FileOutputStream(file);
   9167             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
   9168             dos.writeInt(LAST_DONE_VERSION);
   9169             dos.writeUTF(android.os.Build.VERSION.RELEASE);
   9170             dos.writeUTF(android.os.Build.VERSION.CODENAME);
   9171             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
   9172             dos.writeInt(list.size());
   9173             for (int i=0; i<list.size(); i++) {
   9174                 dos.writeUTF(list.get(i).getPackageName());
   9175                 dos.writeUTF(list.get(i).getClassName());
   9176             }
   9177         } catch (IOException e) {
   9178             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
   9179             file.delete();
   9180         } finally {
   9181             FileUtils.sync(fos);
   9182             if (dos != null) {
   9183                 try {
   9184                     dos.close();
   9185                 } catch (IOException e) {
   9186                     // TODO Auto-generated catch block
   9187                     e.printStackTrace();
   9188                 }
   9189             }
   9190         }
   9191     }
   9192 
   9193     public void systemReady(final Runnable goingCallback) {
   9194         synchronized(this) {
   9195             if (mSystemReady) {
   9196                 if (goingCallback != null) goingCallback.run();
   9197                 return;
   9198             }
   9199 
   9200             // Check to see if there are any update receivers to run.
   9201             if (!mDidUpdate) {
   9202                 if (mWaitingUpdate) {
   9203                     return;
   9204                 }
   9205                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   9206                 List<ResolveInfo> ris = null;
   9207                 try {
   9208                     ris = AppGlobals.getPackageManager().queryIntentReceivers(
   9209                             intent, null, 0, 0);
   9210                 } catch (RemoteException e) {
   9211                 }
   9212                 if (ris != null) {
   9213                     for (int i=ris.size()-1; i>=0; i--) {
   9214                         if ((ris.get(i).activityInfo.applicationInfo.flags
   9215                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
   9216                             ris.remove(i);
   9217                         }
   9218                     }
   9219                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
   9220 
   9221                     ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
   9222 
   9223                     final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
   9224                     for (int i=0; i<ris.size(); i++) {
   9225                         ActivityInfo ai = ris.get(i).activityInfo;
   9226                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   9227                         if (lastDoneReceivers.contains(comp)) {
   9228                             // We already did the pre boot receiver for this app with the current
   9229                             // platform version, so don't do it again...
   9230                             ris.remove(i);
   9231                             i--;
   9232                             // ...however, do keep it as one that has been done, so we don't
   9233                             // forget about it when rewriting the file of last done receivers.
   9234                             doneReceivers.add(comp);
   9235                         }
   9236                     }
   9237 
   9238                     final int[] users = getUsersLocked();
   9239                     for (int i=0; i<ris.size(); i++) {
   9240                         ActivityInfo ai = ris.get(i).activityInfo;
   9241                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   9242                         doneReceivers.add(comp);
   9243                         intent.setComponent(comp);
   9244                         for (int j=0; j<users.length; j++) {
   9245                             IIntentReceiver finisher = null;
   9246                             if (i == ris.size()-1 && j == users.length-1) {
   9247                                 finisher = new IIntentReceiver.Stub() {
   9248                                     public void performReceive(Intent intent, int resultCode,
   9249                                             String data, Bundle extras, boolean ordered,
   9250                                             boolean sticky, int sendingUser) {
   9251                                         // The raw IIntentReceiver interface is called
   9252                                         // with the AM lock held, so redispatch to
   9253                                         // execute our code without the lock.
   9254                                         mHandler.post(new Runnable() {
   9255                                             public void run() {
   9256                                                 synchronized (ActivityManagerService.this) {
   9257                                                     mDidUpdate = true;
   9258                                                 }
   9259                                                 writeLastDonePreBootReceivers(doneReceivers);
   9260                                                 showBootMessage(mContext.getText(
   9261                                                         R.string.android_upgrading_complete),
   9262                                                         false);
   9263                                                 systemReady(goingCallback);
   9264                                             }
   9265                                         });
   9266                                     }
   9267                                 };
   9268                             }
   9269                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
   9270                                     + " for user " + users[j]);
   9271                             broadcastIntentLocked(null, null, intent, null, finisher,
   9272                                     0, null, null, null, AppOpsManager.OP_NONE,
   9273                                     true, false, MY_PID, Process.SYSTEM_UID,
   9274                                     users[j]);
   9275                             if (finisher != null) {
   9276                                 mWaitingUpdate = true;
   9277                             }
   9278                         }
   9279                     }
   9280                 }
   9281                 if (mWaitingUpdate) {
   9282                     return;
   9283                 }
   9284                 mDidUpdate = true;
   9285             }
   9286 
   9287             mAppOpsService.systemReady();
   9288             mSystemReady = true;
   9289             if (!mStartRunning) {
   9290                 return;
   9291             }
   9292         }
   9293 
   9294         ArrayList<ProcessRecord> procsToKill = null;
   9295         synchronized(mPidsSelfLocked) {
   9296             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   9297                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   9298                 if (!isAllowedWhileBooting(proc.info)){
   9299                     if (procsToKill == null) {
   9300                         procsToKill = new ArrayList<ProcessRecord>();
   9301                     }
   9302                     procsToKill.add(proc);
   9303                 }
   9304             }
   9305         }
   9306 
   9307         synchronized(this) {
   9308             if (procsToKill != null) {
   9309                 for (int i=procsToKill.size()-1; i>=0; i--) {
   9310                     ProcessRecord proc = procsToKill.get(i);
   9311                     Slog.i(TAG, "Removing system update proc: " + proc);
   9312                     removeProcessLocked(proc, true, false, "system update done");
   9313                 }
   9314             }
   9315 
   9316             // Now that we have cleaned up any update processes, we
   9317             // are ready to start launching real processes and know that
   9318             // we won't trample on them any more.
   9319             mProcessesReady = true;
   9320         }
   9321 
   9322         Slog.i(TAG, "System now ready");
   9323         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   9324             SystemClock.uptimeMillis());
   9325 
   9326         synchronized(this) {
   9327             // Make sure we have no pre-ready processes sitting around.
   9328 
   9329             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9330                 ResolveInfo ri = mContext.getPackageManager()
   9331                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   9332                                 STOCK_PM_FLAGS);
   9333                 CharSequence errorMsg = null;
   9334                 if (ri != null) {
   9335                     ActivityInfo ai = ri.activityInfo;
   9336                     ApplicationInfo app = ai.applicationInfo;
   9337                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   9338                         mTopAction = Intent.ACTION_FACTORY_TEST;
   9339                         mTopData = null;
   9340                         mTopComponent = new ComponentName(app.packageName,
   9341                                 ai.name);
   9342                     } else {
   9343                         errorMsg = mContext.getResources().getText(
   9344                                 com.android.internal.R.string.factorytest_not_system);
   9345                     }
   9346                 } else {
   9347                     errorMsg = mContext.getResources().getText(
   9348                             com.android.internal.R.string.factorytest_no_action);
   9349                 }
   9350                 if (errorMsg != null) {
   9351                     mTopAction = null;
   9352                     mTopData = null;
   9353                     mTopComponent = null;
   9354                     Message msg = Message.obtain();
   9355                     msg.what = SHOW_FACTORY_ERROR_MSG;
   9356                     msg.getData().putCharSequence("msg", errorMsg);
   9357                     mHandler.sendMessage(msg);
   9358                 }
   9359             }
   9360         }
   9361 
   9362         retrieveSettings();
   9363 
   9364         synchronized (this) {
   9365             readGrantedUriPermissionsLocked();
   9366         }
   9367 
   9368         if (goingCallback != null) goingCallback.run();
   9369 
   9370         synchronized (this) {
   9371             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9372                 try {
   9373                     List apps = AppGlobals.getPackageManager().
   9374                         getPersistentApplications(STOCK_PM_FLAGS);
   9375                     if (apps != null) {
   9376                         int N = apps.size();
   9377                         int i;
   9378                         for (i=0; i<N; i++) {
   9379                             ApplicationInfo info
   9380                                 = (ApplicationInfo)apps.get(i);
   9381                             if (info != null &&
   9382                                     !info.packageName.equals("android")) {
   9383                                 addAppLocked(info, false);
   9384                             }
   9385                         }
   9386                     }
   9387                 } catch (RemoteException ex) {
   9388                     // pm is in same process, this will never happen.
   9389                 }
   9390             }
   9391 
   9392             // Start up initial activity.
   9393             mBooting = true;
   9394 
   9395             try {
   9396                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   9397                     Message msg = Message.obtain();
   9398                     msg.what = SHOW_UID_ERROR_MSG;
   9399                     mHandler.sendMessage(msg);
   9400                 }
   9401             } catch (RemoteException e) {
   9402             }
   9403 
   9404             long ident = Binder.clearCallingIdentity();
   9405             try {
   9406                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   9407                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   9408                         | Intent.FLAG_RECEIVER_FOREGROUND);
   9409                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9410                 broadcastIntentLocked(null, null, intent,
   9411                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   9412                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   9413                 intent = new Intent(Intent.ACTION_USER_STARTING);
   9414                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   9415                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9416                 broadcastIntentLocked(null, null, intent,
   9417                         null, new IIntentReceiver.Stub() {
   9418                             @Override
   9419                             public void performReceive(Intent intent, int resultCode, String data,
   9420                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   9421                                     throws RemoteException {
   9422                             }
   9423                         }, 0, null, null,
   9424                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   9425                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   9426             } finally {
   9427                 Binder.restoreCallingIdentity(ident);
   9428             }
   9429             mStackSupervisor.resumeTopActivitiesLocked();
   9430             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   9431         }
   9432     }
   9433 
   9434     private boolean makeAppCrashingLocked(ProcessRecord app,
   9435             String shortMsg, String longMsg, String stackTrace) {
   9436         app.crashing = true;
   9437         app.crashingReport = generateProcessError(app,
   9438                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   9439         startAppProblemLocked(app);
   9440         app.stopFreezingAllLocked();
   9441         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
   9442     }
   9443 
   9444     private void makeAppNotRespondingLocked(ProcessRecord app,
   9445             String activity, String shortMsg, String longMsg) {
   9446         app.notResponding = true;
   9447         app.notRespondingReport = generateProcessError(app,
   9448                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   9449                 activity, shortMsg, longMsg, null);
   9450         startAppProblemLocked(app);
   9451         app.stopFreezingAllLocked();
   9452     }
   9453 
   9454     /**
   9455      * Generate a process error record, suitable for attachment to a ProcessRecord.
   9456      *
   9457      * @param app The ProcessRecord in which the error occurred.
   9458      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   9459      *                      ActivityManager.AppErrorStateInfo
   9460      * @param activity The activity associated with the crash, if known.
   9461      * @param shortMsg Short message describing the crash.
   9462      * @param longMsg Long message describing the crash.
   9463      * @param stackTrace Full crash stack trace, may be null.
   9464      *
   9465      * @return Returns a fully-formed AppErrorStateInfo record.
   9466      */
   9467     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   9468             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   9469         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   9470 
   9471         report.condition = condition;
   9472         report.processName = app.processName;
   9473         report.pid = app.pid;
   9474         report.uid = app.info.uid;
   9475         report.tag = activity;
   9476         report.shortMsg = shortMsg;
   9477         report.longMsg = longMsg;
   9478         report.stackTrace = stackTrace;
   9479 
   9480         return report;
   9481     }
   9482 
   9483     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   9484         synchronized (this) {
   9485             app.crashing = false;
   9486             app.crashingReport = null;
   9487             app.notResponding = false;
   9488             app.notRespondingReport = null;
   9489             if (app.anrDialog == fromDialog) {
   9490                 app.anrDialog = null;
   9491             }
   9492             if (app.waitDialog == fromDialog) {
   9493                 app.waitDialog = null;
   9494             }
   9495             if (app.pid > 0 && app.pid != MY_PID) {
   9496                 handleAppCrashLocked(app, null, null, null);
   9497                 killUnneededProcessLocked(app, "user request after error");
   9498             }
   9499         }
   9500     }
   9501 
   9502     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
   9503             String stackTrace) {
   9504         if (mHeadless) {
   9505             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   9506             return false;
   9507         }
   9508         long now = SystemClock.uptimeMillis();
   9509 
   9510         Long crashTime;
   9511         if (!app.isolated) {
   9512             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   9513         } else {
   9514             crashTime = null;
   9515         }
   9516         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   9517             // This process loses!
   9518             Slog.w(TAG, "Process " + app.info.processName
   9519                     + " has crashed too many times: killing!");
   9520             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   9521                     app.userId, app.info.processName, app.uid);
   9522             mStackSupervisor.handleAppCrashLocked(app);
   9523             if (!app.persistent) {
   9524                 // We don't want to start this process again until the user
   9525                 // explicitly does so...  but for persistent process, we really
   9526                 // need to keep it running.  If a persistent process is actually
   9527                 // repeatedly crashing, then badness for everyone.
   9528                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   9529                         app.info.processName);
   9530                 if (!app.isolated) {
   9531                     // XXX We don't have a way to mark isolated processes
   9532                     // as bad, since they don't have a peristent identity.
   9533                     mBadProcesses.put(app.info.processName, app.uid,
   9534                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
   9535                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   9536                 }
   9537                 app.bad = true;
   9538                 app.removed = true;
   9539                 // Don't let services in this process be restarted and potentially
   9540                 // annoy the user repeatedly.  Unless it is persistent, since those
   9541                 // processes run critical code.
   9542                 removeProcessLocked(app, false, false, "crash");
   9543                 mStackSupervisor.resumeTopActivitiesLocked();
   9544                 return false;
   9545             }
   9546             mStackSupervisor.resumeTopActivitiesLocked();
   9547         } else {
   9548             mStackSupervisor.finishTopRunningActivityLocked(app);
   9549         }
   9550 
   9551         // Bump up the crash count of any services currently running in the proc.
   9552         for (int i=app.services.size()-1; i>=0; i--) {
   9553             // Any services running in the application need to be placed
   9554             // back in the pending list.
   9555             ServiceRecord sr = app.services.valueAt(i);
   9556             sr.crashCount++;
   9557         }
   9558 
   9559         // If the crashing process is what we consider to be the "home process" and it has been
   9560         // replaced by a third-party app, clear the package preferred activities from packages
   9561         // with a home activity running in the process to prevent a repeatedly crashing app
   9562         // from blocking the user to manually clear the list.
   9563         final ArrayList<ActivityRecord> activities = app.activities;
   9564         if (app == mHomeProcess && activities.size() > 0
   9565                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   9566             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   9567                 final ActivityRecord r = activities.get(activityNdx);
   9568                 if (r.isHomeActivity()) {
   9569                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   9570                     try {
   9571                         ActivityThread.getPackageManager()
   9572                                 .clearPackagePreferredActivities(r.packageName);
   9573                     } catch (RemoteException c) {
   9574                         // pm is in same process, this will never happen.
   9575                     }
   9576                 }
   9577             }
   9578         }
   9579 
   9580         if (!app.isolated) {
   9581             // XXX Can't keep track of crash times for isolated processes,
   9582             // because they don't have a perisistent identity.
   9583             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   9584         }
   9585 
   9586         return true;
   9587     }
   9588 
   9589     void startAppProblemLocked(ProcessRecord app) {
   9590         if (app.userId == mCurrentUserId) {
   9591             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   9592                     mContext, app.info.packageName, app.info.flags);
   9593         } else {
   9594             // If this app is not running under the current user, then we
   9595             // can't give it a report button because that would require
   9596             // launching the report UI under a different user.
   9597             app.errorReportReceiver = null;
   9598         }
   9599         skipCurrentReceiverLocked(app);
   9600     }
   9601 
   9602     void skipCurrentReceiverLocked(ProcessRecord app) {
   9603         for (BroadcastQueue queue : mBroadcastQueues) {
   9604             queue.skipCurrentReceiverLocked(app);
   9605         }
   9606     }
   9607 
   9608     /**
   9609      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   9610      * The application process will exit immediately after this call returns.
   9611      * @param app object of the crashing app, null for the system server
   9612      * @param crashInfo describing the exception
   9613      */
   9614     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   9615         ProcessRecord r = findAppProcess(app, "Crash");
   9616         final String processName = app == null ? "system_server"
   9617                 : (r == null ? "unknown" : r.processName);
   9618 
   9619         handleApplicationCrashInner("crash", r, processName, crashInfo);
   9620     }
   9621 
   9622     /* Native crash reporting uses this inner version because it needs to be somewhat
   9623      * decoupled from the AM-managed cleanup lifecycle
   9624      */
   9625     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   9626             ApplicationErrorReport.CrashInfo crashInfo) {
   9627         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   9628                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   9629                 r == null ? -1 : r.info.flags,
   9630                 crashInfo.exceptionClassName,
   9631                 crashInfo.exceptionMessage,
   9632                 crashInfo.throwFileName,
   9633                 crashInfo.throwLineNumber);
   9634 
   9635         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   9636 
   9637         crashApplication(r, crashInfo);
   9638     }
   9639 
   9640     public void handleApplicationStrictModeViolation(
   9641             IBinder app,
   9642             int violationMask,
   9643             StrictMode.ViolationInfo info) {
   9644         ProcessRecord r = findAppProcess(app, "StrictMode");
   9645         if (r == null) {
   9646             return;
   9647         }
   9648 
   9649         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   9650             Integer stackFingerprint = info.hashCode();
   9651             boolean logIt = true;
   9652             synchronized (mAlreadyLoggedViolatedStacks) {
   9653                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   9654                     logIt = false;
   9655                     // TODO: sub-sample into EventLog for these, with
   9656                     // the info.durationMillis?  Then we'd get
   9657                     // the relative pain numbers, without logging all
   9658                     // the stack traces repeatedly.  We'd want to do
   9659                     // likewise in the client code, which also does
   9660                     // dup suppression, before the Binder call.
   9661                 } else {
   9662                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   9663                         mAlreadyLoggedViolatedStacks.clear();
   9664                     }
   9665                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   9666                 }
   9667             }
   9668             if (logIt) {
   9669                 logStrictModeViolationToDropBox(r, info);
   9670             }
   9671         }
   9672 
   9673         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   9674             AppErrorResult result = new AppErrorResult();
   9675             synchronized (this) {
   9676                 final long origId = Binder.clearCallingIdentity();
   9677 
   9678                 Message msg = Message.obtain();
   9679                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   9680                 HashMap<String, Object> data = new HashMap<String, Object>();
   9681                 data.put("result", result);
   9682                 data.put("app", r);
   9683                 data.put("violationMask", violationMask);
   9684                 data.put("info", info);
   9685                 msg.obj = data;
   9686                 mHandler.sendMessage(msg);
   9687 
   9688                 Binder.restoreCallingIdentity(origId);
   9689             }
   9690             int res = result.get();
   9691             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   9692         }
   9693     }
   9694 
   9695     // Depending on the policy in effect, there could be a bunch of
   9696     // these in quick succession so we try to batch these together to
   9697     // minimize disk writes, number of dropbox entries, and maximize
   9698     // compression, by having more fewer, larger records.
   9699     private void logStrictModeViolationToDropBox(
   9700             ProcessRecord process,
   9701             StrictMode.ViolationInfo info) {
   9702         if (info == null) {
   9703             return;
   9704         }
   9705         final boolean isSystemApp = process == null ||
   9706                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   9707                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   9708         final String processName = process == null ? "unknown" : process.processName;
   9709         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   9710         final DropBoxManager dbox = (DropBoxManager)
   9711                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9712 
   9713         // Exit early if the dropbox isn't configured to accept this report type.
   9714         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9715 
   9716         boolean bufferWasEmpty;
   9717         boolean needsFlush;
   9718         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   9719         synchronized (sb) {
   9720             bufferWasEmpty = sb.length() == 0;
   9721             appendDropBoxProcessHeaders(process, processName, sb);
   9722             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9723             sb.append("System-App: ").append(isSystemApp).append("\n");
   9724             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   9725             if (info.violationNumThisLoop != 0) {
   9726                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   9727             }
   9728             if (info.numAnimationsRunning != 0) {
   9729                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   9730             }
   9731             if (info.broadcastIntentAction != null) {
   9732                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   9733             }
   9734             if (info.durationMillis != -1) {
   9735                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   9736             }
   9737             if (info.numInstances != -1) {
   9738                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   9739             }
   9740             if (info.tags != null) {
   9741                 for (String tag : info.tags) {
   9742                     sb.append("Span-Tag: ").append(tag).append("\n");
   9743                 }
   9744             }
   9745             sb.append("\n");
   9746             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   9747                 sb.append(info.crashInfo.stackTrace);
   9748             }
   9749             sb.append("\n");
   9750 
   9751             // Only buffer up to ~64k.  Various logging bits truncate
   9752             // things at 128k.
   9753             needsFlush = (sb.length() > 64 * 1024);
   9754         }
   9755 
   9756         // Flush immediately if the buffer's grown too large, or this
   9757         // is a non-system app.  Non-system apps are isolated with a
   9758         // different tag & policy and not batched.
   9759         //
   9760         // Batching is useful during internal testing with
   9761         // StrictMode settings turned up high.  Without batching,
   9762         // thousands of separate files could be created on boot.
   9763         if (!isSystemApp || needsFlush) {
   9764             new Thread("Error dump: " + dropboxTag) {
   9765                 @Override
   9766                 public void run() {
   9767                     String report;
   9768                     synchronized (sb) {
   9769                         report = sb.toString();
   9770                         sb.delete(0, sb.length());
   9771                         sb.trimToSize();
   9772                     }
   9773                     if (report.length() != 0) {
   9774                         dbox.addText(dropboxTag, report);
   9775                     }
   9776                 }
   9777             }.start();
   9778             return;
   9779         }
   9780 
   9781         // System app batching:
   9782         if (!bufferWasEmpty) {
   9783             // An existing dropbox-writing thread is outstanding, so
   9784             // we don't need to start it up.  The existing thread will
   9785             // catch the buffer appends we just did.
   9786             return;
   9787         }
   9788 
   9789         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   9790         // (After this point, we shouldn't access AMS internal data structures.)
   9791         new Thread("Error dump: " + dropboxTag) {
   9792             @Override
   9793             public void run() {
   9794                 // 5 second sleep to let stacks arrive and be batched together
   9795                 try {
   9796                     Thread.sleep(5000);  // 5 seconds
   9797                 } catch (InterruptedException e) {}
   9798 
   9799                 String errorReport;
   9800                 synchronized (mStrictModeBuffer) {
   9801                     errorReport = mStrictModeBuffer.toString();
   9802                     if (errorReport.length() == 0) {
   9803                         return;
   9804                     }
   9805                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   9806                     mStrictModeBuffer.trimToSize();
   9807                 }
   9808                 dbox.addText(dropboxTag, errorReport);
   9809             }
   9810         }.start();
   9811     }
   9812 
   9813     /**
   9814      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   9815      * @param app object of the crashing app, null for the system server
   9816      * @param tag reported by the caller
   9817      * @param crashInfo describing the context of the error
   9818      * @return true if the process should exit immediately (WTF is fatal)
   9819      */
   9820     public boolean handleApplicationWtf(IBinder app, String tag,
   9821             ApplicationErrorReport.CrashInfo crashInfo) {
   9822         ProcessRecord r = findAppProcess(app, "WTF");
   9823         final String processName = app == null ? "system_server"
   9824                 : (r == null ? "unknown" : r.processName);
   9825 
   9826         EventLog.writeEvent(EventLogTags.AM_WTF,
   9827                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
   9828                 processName,
   9829                 r == null ? -1 : r.info.flags,
   9830                 tag, crashInfo.exceptionMessage);
   9831 
   9832         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   9833 
   9834         if (r != null && r.pid != Process.myPid() &&
   9835                 Settings.Global.getInt(mContext.getContentResolver(),
   9836                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   9837             crashApplication(r, crashInfo);
   9838             return true;
   9839         } else {
   9840             return false;
   9841         }
   9842     }
   9843 
   9844     /**
   9845      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   9846      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   9847      */
   9848     private ProcessRecord findAppProcess(IBinder app, String reason) {
   9849         if (app == null) {
   9850             return null;
   9851         }
   9852 
   9853         synchronized (this) {
   9854             final int NP = mProcessNames.getMap().size();
   9855             for (int ip=0; ip<NP; ip++) {
   9856                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   9857                 final int NA = apps.size();
   9858                 for (int ia=0; ia<NA; ia++) {
   9859                     ProcessRecord p = apps.valueAt(ia);
   9860                     if (p.thread != null && p.thread.asBinder() == app) {
   9861                         return p;
   9862                     }
   9863                 }
   9864             }
   9865 
   9866             Slog.w(TAG, "Can't find mystery application for " + reason
   9867                     + " from pid=" + Binder.getCallingPid()
   9868                     + " uid=" + Binder.getCallingUid() + ": " + app);
   9869             return null;
   9870         }
   9871     }
   9872 
   9873     /**
   9874      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   9875      * to append various headers to the dropbox log text.
   9876      */
   9877     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   9878             StringBuilder sb) {
   9879         // Watchdog thread ends up invoking this function (with
   9880         // a null ProcessRecord) to add the stack file to dropbox.
   9881         // Do not acquire a lock on this (am) in such cases, as it
   9882         // could cause a potential deadlock, if and when watchdog
   9883         // is invoked due to unavailability of lock on am and it
   9884         // would prevent watchdog from killing system_server.
   9885         if (process == null) {
   9886             sb.append("Process: ").append(processName).append("\n");
   9887             return;
   9888         }
   9889         // Note: ProcessRecord 'process' is guarded by the service
   9890         // instance.  (notably process.pkgList, which could otherwise change
   9891         // concurrently during execution of this method)
   9892         synchronized (this) {
   9893             sb.append("Process: ").append(processName).append("\n");
   9894             int flags = process.info.flags;
   9895             IPackageManager pm = AppGlobals.getPackageManager();
   9896             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   9897             for (int ip=0; ip<process.pkgList.size(); ip++) {
   9898                 String pkg = process.pkgList.keyAt(ip);
   9899                 sb.append("Package: ").append(pkg);
   9900                 try {
   9901                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   9902                     if (pi != null) {
   9903                         sb.append(" v").append(pi.versionCode);
   9904                         if (pi.versionName != null) {
   9905                             sb.append(" (").append(pi.versionName).append(")");
   9906                         }
   9907                     }
   9908                 } catch (RemoteException e) {
   9909                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   9910                 }
   9911                 sb.append("\n");
   9912             }
   9913         }
   9914     }
   9915 
   9916     private static String processClass(ProcessRecord process) {
   9917         if (process == null || process.pid == MY_PID) {
   9918             return "system_server";
   9919         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   9920             return "system_app";
   9921         } else {
   9922             return "data_app";
   9923         }
   9924     }
   9925 
   9926     /**
   9927      * Write a description of an error (crash, WTF, ANR) to the drop box.
   9928      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   9929      * @param process which caused the error, null means the system server
   9930      * @param activity which triggered the error, null if unknown
   9931      * @param parent activity related to the error, null if unknown
   9932      * @param subject line related to the error, null if absent
   9933      * @param report in long form describing the error, null if absent
   9934      * @param logFile to include in the report, null if none
   9935      * @param crashInfo giving an application stack trace, null if absent
   9936      */
   9937     public void addErrorToDropBox(String eventType,
   9938             ProcessRecord process, String processName, ActivityRecord activity,
   9939             ActivityRecord parent, String subject,
   9940             final String report, final File logFile,
   9941             final ApplicationErrorReport.CrashInfo crashInfo) {
   9942         // NOTE -- this must never acquire the ActivityManagerService lock,
   9943         // otherwise the watchdog may be prevented from resetting the system.
   9944 
   9945         final String dropboxTag = processClass(process) + "_" + eventType;
   9946         final DropBoxManager dbox = (DropBoxManager)
   9947                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9948 
   9949         // Exit early if the dropbox isn't configured to accept this report type.
   9950         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9951 
   9952         final StringBuilder sb = new StringBuilder(1024);
   9953         appendDropBoxProcessHeaders(process, processName, sb);
   9954         if (activity != null) {
   9955             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   9956         }
   9957         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   9958             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   9959         }
   9960         if (parent != null && parent != activity) {
   9961             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   9962         }
   9963         if (subject != null) {
   9964             sb.append("Subject: ").append(subject).append("\n");
   9965         }
   9966         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9967         if (Debug.isDebuggerConnected()) {
   9968             sb.append("Debugger: Connected\n");
   9969         }
   9970         sb.append("\n");
   9971 
   9972         // Do the rest in a worker thread to avoid blocking the caller on I/O
   9973         // (After this point, we shouldn't access AMS internal data structures.)
   9974         Thread worker = new Thread("Error dump: " + dropboxTag) {
   9975             @Override
   9976             public void run() {
   9977                 if (report != null) {
   9978                     sb.append(report);
   9979                 }
   9980                 if (logFile != null) {
   9981                     try {
   9982                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
   9983                                     "\n\n[[TRUNCATED]]"));
   9984                     } catch (IOException e) {
   9985                         Slog.e(TAG, "Error reading " + logFile, e);
   9986                     }
   9987                 }
   9988                 if (crashInfo != null && crashInfo.stackTrace != null) {
   9989                     sb.append(crashInfo.stackTrace);
   9990                 }
   9991 
   9992                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   9993                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   9994                 if (lines > 0) {
   9995                     sb.append("\n");
   9996 
   9997                     // Merge several logcat streams, and take the last N lines
   9998                     InputStreamReader input = null;
   9999                     try {
   10000                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   10001                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   10002                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   10003 
   10004                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   10005                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   10006                         input = new InputStreamReader(logcat.getInputStream());
   10007 
   10008                         int num;
   10009                         char[] buf = new char[8192];
   10010                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   10011                     } catch (IOException e) {
   10012                         Slog.e(TAG, "Error running logcat", e);
   10013                     } finally {
   10014                         if (input != null) try { input.close(); } catch (IOException e) {}
   10015                     }
   10016                 }
   10017 
   10018                 dbox.addText(dropboxTag, sb.toString());
   10019             }
   10020         };
   10021 
   10022         if (process == null) {
   10023             // If process is null, we are being called from some internal code
   10024             // and may be about to die -- run this synchronously.
   10025             worker.run();
   10026         } else {
   10027             worker.start();
   10028         }
   10029     }
   10030 
   10031     /**
   10032      * Bring up the "unexpected error" dialog box for a crashing app.
   10033      * Deal with edge cases (intercepts from instrumented applications,
   10034      * ActivityController, error intent receivers, that sort of thing).
   10035      * @param r the application crashing
   10036      * @param crashInfo describing the failure
   10037      */
   10038     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   10039         long timeMillis = System.currentTimeMillis();
   10040         String shortMsg = crashInfo.exceptionClassName;
   10041         String longMsg = crashInfo.exceptionMessage;
   10042         String stackTrace = crashInfo.stackTrace;
   10043         if (shortMsg != null && longMsg != null) {
   10044             longMsg = shortMsg + ": " + longMsg;
   10045         } else if (shortMsg != null) {
   10046             longMsg = shortMsg;
   10047         }
   10048 
   10049         AppErrorResult result = new AppErrorResult();
   10050         synchronized (this) {
   10051             if (mController != null) {
   10052                 try {
   10053                     String name = r != null ? r.processName : null;
   10054                     int pid = r != null ? r.pid : Binder.getCallingPid();
   10055                     if (!mController.appCrashed(name, pid,
   10056                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   10057                         Slog.w(TAG, "Force-killing crashed app " + name
   10058                                 + " at watcher's request");
   10059                         Process.killProcess(pid);
   10060                         return;
   10061                     }
   10062                 } catch (RemoteException e) {
   10063                     mController = null;
   10064                     Watchdog.getInstance().setActivityController(null);
   10065                 }
   10066             }
   10067 
   10068             final long origId = Binder.clearCallingIdentity();
   10069 
   10070             // If this process is running instrumentation, finish it.
   10071             if (r != null && r.instrumentationClass != null) {
   10072                 Slog.w(TAG, "Error in app " + r.processName
   10073                       + " running instrumentation " + r.instrumentationClass + ":");
   10074                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   10075                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   10076                 Bundle info = new Bundle();
   10077                 info.putString("shortMsg", shortMsg);
   10078                 info.putString("longMsg", longMsg);
   10079                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   10080                 Binder.restoreCallingIdentity(origId);
   10081                 return;
   10082             }
   10083 
   10084             // If we can't identify the process or it's already exceeded its crash quota,
   10085             // quit right away without showing a crash dialog.
   10086             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   10087                 Binder.restoreCallingIdentity(origId);
   10088                 return;
   10089             }
   10090 
   10091             Message msg = Message.obtain();
   10092             msg.what = SHOW_ERROR_MSG;
   10093             HashMap data = new HashMap();
   10094             data.put("result", result);
   10095             data.put("app", r);
   10096             msg.obj = data;
   10097             mHandler.sendMessage(msg);
   10098 
   10099             Binder.restoreCallingIdentity(origId);
   10100         }
   10101 
   10102         int res = result.get();
   10103 
   10104         Intent appErrorIntent = null;
   10105         synchronized (this) {
   10106             if (r != null && !r.isolated) {
   10107                 // XXX Can't keep track of crash time for isolated processes,
   10108                 // since they don't have a persistent identity.
   10109                 mProcessCrashTimes.put(r.info.processName, r.uid,
   10110                         SystemClock.uptimeMillis());
   10111             }
   10112             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   10113                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   10114             }
   10115         }
   10116 
   10117         if (appErrorIntent != null) {
   10118             try {
   10119                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   10120             } catch (ActivityNotFoundException e) {
   10121                 Slog.w(TAG, "bug report receiver dissappeared", e);
   10122             }
   10123         }
   10124     }
   10125 
   10126     Intent createAppErrorIntentLocked(ProcessRecord r,
   10127             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   10128         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   10129         if (report == null) {
   10130             return null;
   10131         }
   10132         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   10133         result.setComponent(r.errorReportReceiver);
   10134         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   10135         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   10136         return result;
   10137     }
   10138 
   10139     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   10140             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   10141         if (r.errorReportReceiver == null) {
   10142             return null;
   10143         }
   10144 
   10145         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   10146             return null;
   10147         }
   10148 
   10149         ApplicationErrorReport report = new ApplicationErrorReport();
   10150         report.packageName = r.info.packageName;
   10151         report.installerPackageName = r.errorReportReceiver.getPackageName();
   10152         report.processName = r.processName;
   10153         report.time = timeMillis;
   10154         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10155 
   10156         if (r.crashing || r.forceCrashReport) {
   10157             report.type = ApplicationErrorReport.TYPE_CRASH;
   10158             report.crashInfo = crashInfo;
   10159         } else if (r.notResponding) {
   10160             report.type = ApplicationErrorReport.TYPE_ANR;
   10161             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   10162 
   10163             report.anrInfo.activity = r.notRespondingReport.tag;
   10164             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   10165             report.anrInfo.info = r.notRespondingReport.longMsg;
   10166         }
   10167 
   10168         return report;
   10169     }
   10170 
   10171     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   10172         enforceNotIsolatedCaller("getProcessesInErrorState");
   10173         // assume our apps are happy - lazy create the list
   10174         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   10175 
   10176         final boolean allUsers = ActivityManager.checkUidPermission(
   10177                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10178                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10179         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10180 
   10181         synchronized (this) {
   10182 
   10183             // iterate across all processes
   10184             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10185                 ProcessRecord app = mLruProcesses.get(i);
   10186                 if (!allUsers && app.userId != userId) {
   10187                     continue;
   10188                 }
   10189                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   10190                     // This one's in trouble, so we'll generate a report for it
   10191                     // crashes are higher priority (in case there's a crash *and* an anr)
   10192                     ActivityManager.ProcessErrorStateInfo report = null;
   10193                     if (app.crashing) {
   10194                         report = app.crashingReport;
   10195                     } else if (app.notResponding) {
   10196                         report = app.notRespondingReport;
   10197                     }
   10198 
   10199                     if (report != null) {
   10200                         if (errList == null) {
   10201                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   10202                         }
   10203                         errList.add(report);
   10204                     } else {
   10205                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   10206                                 " crashing = " + app.crashing +
   10207                                 " notResponding = " + app.notResponding);
   10208                     }
   10209                 }
   10210             }
   10211         }
   10212 
   10213         return errList;
   10214     }
   10215 
   10216     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   10217         if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   10218             if (currApp != null) {
   10219                 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
   10220             }
   10221             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10222         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   10223             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10224         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   10225             if (currApp != null) {
   10226                 currApp.lru = 0;
   10227             }
   10228             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10229         } else if (adj >= ProcessList.SERVICE_ADJ) {
   10230             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10231         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10232             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   10233         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10234             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   10235         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   10236             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   10237         } else {
   10238             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   10239         }
   10240     }
   10241 
   10242     private void fillInProcMemInfo(ProcessRecord app,
   10243             ActivityManager.RunningAppProcessInfo outInfo) {
   10244         outInfo.pid = app.pid;
   10245         outInfo.uid = app.info.uid;
   10246         if (mHeavyWeightProcess == app) {
   10247             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   10248         }
   10249         if (app.persistent) {
   10250             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   10251         }
   10252         if (app.activities.size() > 0) {
   10253             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   10254         }
   10255         outInfo.lastTrimLevel = app.trimMemoryLevel;
   10256         int adj = app.curAdj;
   10257         outInfo.importance = oomAdjToImportance(adj, outInfo);
   10258         outInfo.importanceReasonCode = app.adjTypeCode;
   10259     }
   10260 
   10261     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   10262         enforceNotIsolatedCaller("getRunningAppProcesses");
   10263         // Lazy instantiation of list
   10264         List<ActivityManager.RunningAppProcessInfo> runList = null;
   10265         final boolean allUsers = ActivityManager.checkUidPermission(
   10266                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10267                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10268         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10269         synchronized (this) {
   10270             // Iterate across all processes
   10271             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10272                 ProcessRecord app = mLruProcesses.get(i);
   10273                 if (!allUsers && app.userId != userId) {
   10274                     continue;
   10275                 }
   10276                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   10277                     // Generate process state info for running application
   10278                     ActivityManager.RunningAppProcessInfo currApp =
   10279                         new ActivityManager.RunningAppProcessInfo(app.processName,
   10280                                 app.pid, app.getPackageList());
   10281                     fillInProcMemInfo(app, currApp);
   10282                     if (app.adjSource instanceof ProcessRecord) {
   10283                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   10284                         currApp.importanceReasonImportance = oomAdjToImportance(
   10285                                 app.adjSourceOom, null);
   10286                     } else if (app.adjSource instanceof ActivityRecord) {
   10287                         ActivityRecord r = (ActivityRecord)app.adjSource;
   10288                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   10289                     }
   10290                     if (app.adjTarget instanceof ComponentName) {
   10291                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   10292                     }
   10293                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   10294                     //        + " lru=" + currApp.lru);
   10295                     if (runList == null) {
   10296                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   10297                     }
   10298                     runList.add(currApp);
   10299                 }
   10300             }
   10301         }
   10302         return runList;
   10303     }
   10304 
   10305     public List<ApplicationInfo> getRunningExternalApplications() {
   10306         enforceNotIsolatedCaller("getRunningExternalApplications");
   10307         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   10308         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   10309         if (runningApps != null && runningApps.size() > 0) {
   10310             Set<String> extList = new HashSet<String>();
   10311             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   10312                 if (app.pkgList != null) {
   10313                     for (String pkg : app.pkgList) {
   10314                         extList.add(pkg);
   10315                     }
   10316                 }
   10317             }
   10318             IPackageManager pm = AppGlobals.getPackageManager();
   10319             for (String pkg : extList) {
   10320                 try {
   10321                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   10322                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   10323                         retList.add(info);
   10324                     }
   10325                 } catch (RemoteException e) {
   10326                 }
   10327             }
   10328         }
   10329         return retList;
   10330     }
   10331 
   10332     @Override
   10333     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   10334         enforceNotIsolatedCaller("getMyMemoryState");
   10335         synchronized (this) {
   10336             ProcessRecord proc;
   10337             synchronized (mPidsSelfLocked) {
   10338                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   10339             }
   10340             fillInProcMemInfo(proc, outInfo);
   10341         }
   10342     }
   10343 
   10344     @Override
   10345     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   10346         if (checkCallingPermission(android.Manifest.permission.DUMP)
   10347                 != PackageManager.PERMISSION_GRANTED) {
   10348             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   10349                     + Binder.getCallingPid()
   10350                     + ", uid=" + Binder.getCallingUid()
   10351                     + " without permission "
   10352                     + android.Manifest.permission.DUMP);
   10353             return;
   10354         }
   10355 
   10356         boolean dumpAll = false;
   10357         boolean dumpClient = false;
   10358         String dumpPackage = null;
   10359 
   10360         int opti = 0;
   10361         while (opti < args.length) {
   10362             String opt = args[opti];
   10363             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10364                 break;
   10365             }
   10366             opti++;
   10367             if ("-a".equals(opt)) {
   10368                 dumpAll = true;
   10369             } else if ("-c".equals(opt)) {
   10370                 dumpClient = true;
   10371             } else if ("-h".equals(opt)) {
   10372                 pw.println("Activity manager dump options:");
   10373                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   10374                 pw.println("  cmd may be one of:");
   10375                 pw.println("    a[ctivities]: activity stack state");
   10376                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   10377                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   10378                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   10379                 pw.println("    o[om]: out of memory management");
   10380                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   10381                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   10382                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   10383                 pw.println("    service [COMP_SPEC]: service client-side state");
   10384                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   10385                 pw.println("    all: dump all activities");
   10386                 pw.println("    top: dump the top activity");
   10387                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   10388                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   10389                 pw.println("    a partial substring in a component name, a");
   10390                 pw.println("    hex object identifier.");
   10391                 pw.println("  -a: include all available server state.");
   10392                 pw.println("  -c: include client state.");
   10393                 return;
   10394             } else {
   10395                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10396             }
   10397         }
   10398 
   10399         long origId = Binder.clearCallingIdentity();
   10400         boolean more = false;
   10401         // Is the caller requesting to dump a particular piece of data?
   10402         if (opti < args.length) {
   10403             String cmd = args[opti];
   10404             opti++;
   10405             if ("activities".equals(cmd) || "a".equals(cmd)) {
   10406                 synchronized (this) {
   10407                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   10408                 }
   10409             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   10410                 String[] newArgs;
   10411                 String name;
   10412                 if (opti >= args.length) {
   10413                     name = null;
   10414                     newArgs = EMPTY_STRING_ARRAY;
   10415                 } else {
   10416                     name = args[opti];
   10417                     opti++;
   10418                     newArgs = new String[args.length - opti];
   10419                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10420                             args.length - opti);
   10421                 }
   10422                 synchronized (this) {
   10423                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   10424                 }
   10425             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   10426                 String[] newArgs;
   10427                 String name;
   10428                 if (opti >= args.length) {
   10429                     name = null;
   10430                     newArgs = EMPTY_STRING_ARRAY;
   10431                 } else {
   10432                     name = args[opti];
   10433                     opti++;
   10434                     newArgs = new String[args.length - opti];
   10435                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10436                             args.length - opti);
   10437                 }
   10438                 synchronized (this) {
   10439                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   10440                 }
   10441             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   10442                 String[] newArgs;
   10443                 String name;
   10444                 if (opti >= args.length) {
   10445                     name = null;
   10446                     newArgs = EMPTY_STRING_ARRAY;
   10447                 } else {
   10448                     name = args[opti];
   10449                     opti++;
   10450                     newArgs = new String[args.length - opti];
   10451                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10452                             args.length - opti);
   10453                 }
   10454                 synchronized (this) {
   10455                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   10456                 }
   10457             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   10458                 synchronized (this) {
   10459                     dumpOomLocked(fd, pw, args, opti, true);
   10460                 }
   10461             } else if ("provider".equals(cmd)) {
   10462                 String[] newArgs;
   10463                 String name;
   10464                 if (opti >= args.length) {
   10465                     name = null;
   10466                     newArgs = EMPTY_STRING_ARRAY;
   10467                 } else {
   10468                     name = args[opti];
   10469                     opti++;
   10470                     newArgs = new String[args.length - opti];
   10471                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   10472                 }
   10473                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   10474                     pw.println("No providers match: " + name);
   10475                     pw.println("Use -h for help.");
   10476                 }
   10477             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   10478                 synchronized (this) {
   10479                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   10480                 }
   10481             } else if ("service".equals(cmd)) {
   10482                 String[] newArgs;
   10483                 String name;
   10484                 if (opti >= args.length) {
   10485                     name = null;
   10486                     newArgs = EMPTY_STRING_ARRAY;
   10487                 } else {
   10488                     name = args[opti];
   10489                     opti++;
   10490                     newArgs = new String[args.length - opti];
   10491                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10492                             args.length - opti);
   10493                 }
   10494                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   10495                     pw.println("No services match: " + name);
   10496                     pw.println("Use -h for help.");
   10497                 }
   10498             } else if ("package".equals(cmd)) {
   10499                 String[] newArgs;
   10500                 if (opti >= args.length) {
   10501                     pw.println("package: no package name specified");
   10502                     pw.println("Use -h for help.");
   10503                 } else {
   10504                     dumpPackage = args[opti];
   10505                     opti++;
   10506                     newArgs = new String[args.length - opti];
   10507                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10508                             args.length - opti);
   10509                     args = newArgs;
   10510                     opti = 0;
   10511                     more = true;
   10512                 }
   10513             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   10514                 synchronized (this) {
   10515                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   10516                 }
   10517             } else {
   10518                 // Dumping a single activity?
   10519                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   10520                     pw.println("Bad activity command, or no activities match: " + cmd);
   10521                     pw.println("Use -h for help.");
   10522                 }
   10523             }
   10524             if (!more) {
   10525                 Binder.restoreCallingIdentity(origId);
   10526                 return;
   10527             }
   10528         }
   10529 
   10530         // No piece of data specified, dump everything.
   10531         synchronized (this) {
   10532             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10533             pw.println();
   10534             if (dumpAll) {
   10535                 pw.println("-------------------------------------------------------------------------------");
   10536             }
   10537             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10538             pw.println();
   10539             if (dumpAll) {
   10540                 pw.println("-------------------------------------------------------------------------------");
   10541             }
   10542             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10543             pw.println();
   10544             if (dumpAll) {
   10545                 pw.println("-------------------------------------------------------------------------------");
   10546             }
   10547             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10548             pw.println();
   10549             if (dumpAll) {
   10550                 pw.println("-------------------------------------------------------------------------------");
   10551             }
   10552             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10553             pw.println();
   10554             if (dumpAll) {
   10555                 pw.println("-------------------------------------------------------------------------------");
   10556             }
   10557             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10558         }
   10559         Binder.restoreCallingIdentity(origId);
   10560     }
   10561 
   10562     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10563             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   10564         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   10565 
   10566         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   10567                 dumpPackage);
   10568         boolean needSep = printedAnything;
   10569 
   10570         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   10571                 dumpPackage, needSep, "  mFocusedActivity: ");
   10572         if (printed) {
   10573             printedAnything = true;
   10574             needSep = false;
   10575         }
   10576 
   10577         if (dumpPackage == null) {
   10578             if (needSep) {
   10579                 pw.println();
   10580             }
   10581             needSep = true;
   10582             printedAnything = true;
   10583             mStackSupervisor.dump(pw, "  ");
   10584         }
   10585 
   10586         if (mRecentTasks.size() > 0) {
   10587             boolean printedHeader = false;
   10588 
   10589             final int N = mRecentTasks.size();
   10590             for (int i=0; i<N; i++) {
   10591                 TaskRecord tr = mRecentTasks.get(i);
   10592                 if (dumpPackage != null) {
   10593                     if (tr.realActivity == null ||
   10594                             !dumpPackage.equals(tr.realActivity)) {
   10595                         continue;
   10596                     }
   10597                 }
   10598                 if (!printedHeader) {
   10599                     if (needSep) {
   10600                         pw.println();
   10601                     }
   10602                     pw.println("  Recent tasks:");
   10603                     printedHeader = true;
   10604                     printedAnything = true;
   10605                 }
   10606                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   10607                         pw.println(tr);
   10608                 if (dumpAll) {
   10609                     mRecentTasks.get(i).dump(pw, "    ");
   10610                 }
   10611             }
   10612         }
   10613 
   10614         if (!printedAnything) {
   10615             pw.println("  (nothing)");
   10616         }
   10617     }
   10618 
   10619     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10620             int opti, boolean dumpAll, String dumpPackage) {
   10621         boolean needSep = false;
   10622         boolean printedAnything = false;
   10623         int numPers = 0;
   10624 
   10625         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   10626 
   10627         if (dumpAll) {
   10628             final int NP = mProcessNames.getMap().size();
   10629             for (int ip=0; ip<NP; ip++) {
   10630                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   10631                 final int NA = procs.size();
   10632                 for (int ia=0; ia<NA; ia++) {
   10633                     ProcessRecord r = procs.valueAt(ia);
   10634                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10635                         continue;
   10636                     }
   10637                     if (!needSep) {
   10638                         pw.println("  All known processes:");
   10639                         needSep = true;
   10640                         printedAnything = true;
   10641                     }
   10642                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   10643                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   10644                         pw.print(" "); pw.println(r);
   10645                     r.dump(pw, "    ");
   10646                     if (r.persistent) {
   10647                         numPers++;
   10648                     }
   10649                 }
   10650             }
   10651         }
   10652 
   10653         if (mIsolatedProcesses.size() > 0) {
   10654             boolean printed = false;
   10655             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   10656                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   10657                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10658                     continue;
   10659                 }
   10660                 if (!printed) {
   10661                     if (needSep) {
   10662                         pw.println();
   10663                     }
   10664                     pw.println("  Isolated process list (sorted by uid):");
   10665                     printedAnything = true;
   10666                     printed = true;
   10667                     needSep = true;
   10668                 }
   10669                 pw.println(String.format("%sIsolated #%2d: %s",
   10670                         "    ", i, r.toString()));
   10671             }
   10672         }
   10673 
   10674         if (mLruProcesses.size() > 0) {
   10675             if (needSep) {
   10676                 pw.println();
   10677             }
   10678             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   10679                     pw.print(" total, non-act at ");
   10680                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   10681                     pw.print(", non-svc at ");
   10682                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   10683                     pw.println("):");
   10684             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   10685             needSep = true;
   10686             printedAnything = true;
   10687         }
   10688 
   10689         if (dumpAll || dumpPackage != null) {
   10690             synchronized (mPidsSelfLocked) {
   10691                 boolean printed = false;
   10692                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   10693                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   10694                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10695                         continue;
   10696                     }
   10697                     if (!printed) {
   10698                         if (needSep) pw.println();
   10699                         needSep = true;
   10700                         pw.println("  PID mappings:");
   10701                         printed = true;
   10702                         printedAnything = true;
   10703                     }
   10704                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   10705                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   10706                 }
   10707             }
   10708         }
   10709 
   10710         if (mForegroundProcesses.size() > 0) {
   10711             synchronized (mPidsSelfLocked) {
   10712                 boolean printed = false;
   10713                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   10714                     ProcessRecord r = mPidsSelfLocked.get(
   10715                             mForegroundProcesses.valueAt(i).pid);
   10716                     if (dumpPackage != null && (r == null
   10717                             || !r.pkgList.containsKey(dumpPackage))) {
   10718                         continue;
   10719                     }
   10720                     if (!printed) {
   10721                         if (needSep) pw.println();
   10722                         needSep = true;
   10723                         pw.println("  Foreground Processes:");
   10724                         printed = true;
   10725                         printedAnything = true;
   10726                     }
   10727                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   10728                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   10729                 }
   10730             }
   10731         }
   10732 
   10733         if (mPersistentStartingProcesses.size() > 0) {
   10734             if (needSep) pw.println();
   10735             needSep = true;
   10736             printedAnything = true;
   10737             pw.println("  Persisent processes that are starting:");
   10738             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   10739                     "Starting Norm", "Restarting PERS", dumpPackage);
   10740         }
   10741 
   10742         if (mRemovedProcesses.size() > 0) {
   10743             if (needSep) pw.println();
   10744             needSep = true;
   10745             printedAnything = true;
   10746             pw.println("  Processes that are being removed:");
   10747             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   10748                     "Removed Norm", "Removed PERS", dumpPackage);
   10749         }
   10750 
   10751         if (mProcessesOnHold.size() > 0) {
   10752             if (needSep) pw.println();
   10753             needSep = true;
   10754             printedAnything = true;
   10755             pw.println("  Processes that are on old until the system is ready:");
   10756             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   10757                     "OnHold Norm", "OnHold PERS", dumpPackage);
   10758         }
   10759 
   10760         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   10761 
   10762         if (mProcessCrashTimes.getMap().size() > 0) {
   10763             boolean printed = false;
   10764             long now = SystemClock.uptimeMillis();
   10765             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   10766             final int NP = pmap.size();
   10767             for (int ip=0; ip<NP; ip++) {
   10768                 String pname = pmap.keyAt(ip);
   10769                 SparseArray<Long> uids = pmap.valueAt(ip);
   10770                 final int N = uids.size();
   10771                 for (int i=0; i<N; i++) {
   10772                     int puid = uids.keyAt(i);
   10773                     ProcessRecord r = mProcessNames.get(pname, puid);
   10774                     if (dumpPackage != null && (r == null
   10775                             || !r.pkgList.containsKey(dumpPackage))) {
   10776                         continue;
   10777                     }
   10778                     if (!printed) {
   10779                         if (needSep) pw.println();
   10780                         needSep = true;
   10781                         pw.println("  Time since processes crashed:");
   10782                         printed = true;
   10783                         printedAnything = true;
   10784                     }
   10785                     pw.print("    Process "); pw.print(pname);
   10786                             pw.print(" uid "); pw.print(puid);
   10787                             pw.print(": last crashed ");
   10788                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   10789                             pw.println(" ago");
   10790                 }
   10791             }
   10792         }
   10793 
   10794         if (mBadProcesses.getMap().size() > 0) {
   10795             boolean printed = false;
   10796             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
   10797             final int NP = pmap.size();
   10798             for (int ip=0; ip<NP; ip++) {
   10799                 String pname = pmap.keyAt(ip);
   10800                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
   10801                 final int N = uids.size();
   10802                 for (int i=0; i<N; i++) {
   10803                     int puid = uids.keyAt(i);
   10804                     ProcessRecord r = mProcessNames.get(pname, puid);
   10805                     if (dumpPackage != null && (r == null
   10806                             || !r.pkgList.containsKey(dumpPackage))) {
   10807                         continue;
   10808                     }
   10809                     if (!printed) {
   10810                         if (needSep) pw.println();
   10811                         needSep = true;
   10812                         pw.println("  Bad processes:");
   10813                         printedAnything = true;
   10814                     }
   10815                     BadProcessInfo info = uids.valueAt(i);
   10816                     pw.print("    Bad process "); pw.print(pname);
   10817                             pw.print(" uid "); pw.print(puid);
   10818                             pw.print(": crashed at time "); pw.println(info.time);
   10819                     if (info.shortMsg != null) {
   10820                         pw.print("      Short msg: "); pw.println(info.shortMsg);
   10821                     }
   10822                     if (info.longMsg != null) {
   10823                         pw.print("      Long msg: "); pw.println(info.longMsg);
   10824                     }
   10825                     if (info.stack != null) {
   10826                         pw.println("      Stack:");
   10827                         int lastPos = 0;
   10828                         for (int pos=0; pos<info.stack.length(); pos++) {
   10829                             if (info.stack.charAt(pos) == '\n') {
   10830                                 pw.print("        ");
   10831                                 pw.write(info.stack, lastPos, pos-lastPos);
   10832                                 pw.println();
   10833                                 lastPos = pos+1;
   10834                             }
   10835                         }
   10836                         if (lastPos < info.stack.length()) {
   10837                             pw.print("        ");
   10838                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
   10839                             pw.println();
   10840                         }
   10841                     }
   10842                 }
   10843             }
   10844         }
   10845 
   10846         if (dumpPackage == null) {
   10847             pw.println();
   10848             needSep = false;
   10849             pw.println("  mStartedUsers:");
   10850             for (int i=0; i<mStartedUsers.size(); i++) {
   10851                 UserStartedState uss = mStartedUsers.valueAt(i);
   10852                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   10853                         pw.print(": "); uss.dump("", pw);
   10854             }
   10855             pw.print("  mStartedUserArray: [");
   10856             for (int i=0; i<mStartedUserArray.length; i++) {
   10857                 if (i > 0) pw.print(", ");
   10858                 pw.print(mStartedUserArray[i]);
   10859             }
   10860             pw.println("]");
   10861             pw.print("  mUserLru: [");
   10862             for (int i=0; i<mUserLru.size(); i++) {
   10863                 if (i > 0) pw.print(", ");
   10864                 pw.print(mUserLru.get(i));
   10865             }
   10866             pw.println("]");
   10867             if (dumpAll) {
   10868                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   10869             }
   10870         }
   10871         if (mHomeProcess != null && (dumpPackage == null
   10872                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   10873             if (needSep) {
   10874                 pw.println();
   10875                 needSep = false;
   10876             }
   10877             pw.println("  mHomeProcess: " + mHomeProcess);
   10878         }
   10879         if (mPreviousProcess != null && (dumpPackage == null
   10880                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   10881             if (needSep) {
   10882                 pw.println();
   10883                 needSep = false;
   10884             }
   10885             pw.println("  mPreviousProcess: " + mPreviousProcess);
   10886         }
   10887         if (dumpAll) {
   10888             StringBuilder sb = new StringBuilder(128);
   10889             sb.append("  mPreviousProcessVisibleTime: ");
   10890             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   10891             pw.println(sb);
   10892         }
   10893         if (mHeavyWeightProcess != null && (dumpPackage == null
   10894                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   10895             if (needSep) {
   10896                 pw.println();
   10897                 needSep = false;
   10898             }
   10899             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   10900         }
   10901         if (dumpPackage == null) {
   10902             pw.println("  mConfiguration: " + mConfiguration);
   10903         }
   10904         if (dumpAll) {
   10905             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   10906             if (mCompatModePackages.getPackages().size() > 0) {
   10907                 boolean printed = false;
   10908                 for (Map.Entry<String, Integer> entry
   10909                         : mCompatModePackages.getPackages().entrySet()) {
   10910                     String pkg = entry.getKey();
   10911                     int mode = entry.getValue();
   10912                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   10913                         continue;
   10914                     }
   10915                     if (!printed) {
   10916                         pw.println("  mScreenCompatPackages:");
   10917                         printed = true;
   10918                     }
   10919                     pw.print("    "); pw.print(pkg); pw.print(": ");
   10920                             pw.print(mode); pw.println();
   10921                 }
   10922             }
   10923         }
   10924         if (dumpPackage == null) {
   10925             if (mSleeping || mWentToSleep || mLockScreenShown) {
   10926                 pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   10927                         + " mLockScreenShown " + mLockScreenShown);
   10928             }
   10929             if (mShuttingDown) {
   10930                 pw.println("  mShuttingDown=" + mShuttingDown);
   10931             }
   10932         }
   10933         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   10934                 || mOrigWaitForDebugger) {
   10935             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   10936                     || dumpPackage.equals(mOrigDebugApp)) {
   10937                 if (needSep) {
   10938                     pw.println();
   10939                     needSep = false;
   10940                 }
   10941                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   10942                         + " mDebugTransient=" + mDebugTransient
   10943                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   10944             }
   10945         }
   10946         if (mOpenGlTraceApp != null) {
   10947             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   10948                 if (needSep) {
   10949                     pw.println();
   10950                     needSep = false;
   10951                 }
   10952                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   10953             }
   10954         }
   10955         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   10956                 || mProfileFd != null) {
   10957             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   10958                 if (needSep) {
   10959                     pw.println();
   10960                     needSep = false;
   10961                 }
   10962                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   10963                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   10964                 pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   10965                         + mAutoStopProfiler);
   10966             }
   10967         }
   10968         if (dumpPackage == null) {
   10969             if (mAlwaysFinishActivities || mController != null) {
   10970                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   10971                         + " mController=" + mController);
   10972             }
   10973             if (dumpAll) {
   10974                 pw.println("  Total persistent processes: " + numPers);
   10975                 pw.println("  mStartRunning=" + mStartRunning
   10976                         + " mProcessesReady=" + mProcessesReady
   10977                         + " mSystemReady=" + mSystemReady);
   10978                 pw.println("  mBooting=" + mBooting
   10979                         + " mBooted=" + mBooted
   10980                         + " mFactoryTest=" + mFactoryTest);
   10981                 pw.print("  mLastPowerCheckRealtime=");
   10982                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   10983                         pw.println("");
   10984                 pw.print("  mLastPowerCheckUptime=");
   10985                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   10986                         pw.println("");
   10987                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   10988                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   10989                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   10990                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   10991                         + " (" + mLruProcesses.size() + " total)"
   10992                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   10993                         + " mNumServiceProcs=" + mNumServiceProcs
   10994                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   10995                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   10996                         + " mLastMemoryLevel" + mLastMemoryLevel
   10997                         + " mLastNumProcesses" + mLastNumProcesses);
   10998                 long now = SystemClock.uptimeMillis();
   10999                 pw.print("  mLastIdleTime=");
   11000                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   11001                         pw.print(" mLowRamSinceLastIdle=");
   11002                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   11003                         pw.println();
   11004             }
   11005         }
   11006 
   11007         if (!printedAnything) {
   11008             pw.println("  (nothing)");
   11009         }
   11010     }
   11011 
   11012     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   11013             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   11014         if (mProcessesToGc.size() > 0) {
   11015             boolean printed = false;
   11016             long now = SystemClock.uptimeMillis();
   11017             for (int i=0; i<mProcessesToGc.size(); i++) {
   11018                 ProcessRecord proc = mProcessesToGc.get(i);
   11019                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   11020                     continue;
   11021                 }
   11022                 if (!printed) {
   11023                     if (needSep) pw.println();
   11024                     needSep = true;
   11025                     pw.println("  Processes that are waiting to GC:");
   11026                     printed = true;
   11027                 }
   11028                 pw.print("    Process "); pw.println(proc);
   11029                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   11030                         pw.print(", last gced=");
   11031                         pw.print(now-proc.lastRequestedGc);
   11032                         pw.print(" ms ago, last lowMem=");
   11033                         pw.print(now-proc.lastLowMemory);
   11034                         pw.println(" ms ago");
   11035 
   11036             }
   11037         }
   11038         return needSep;
   11039     }
   11040 
   11041     void printOomLevel(PrintWriter pw, String name, int adj) {
   11042         pw.print("    ");
   11043         if (adj >= 0) {
   11044             pw.print(' ');
   11045             if (adj < 10) pw.print(' ');
   11046         } else {
   11047             if (adj > -10) pw.print(' ');
   11048         }
   11049         pw.print(adj);
   11050         pw.print(": ");
   11051         pw.print(name);
   11052         pw.print(" (");
   11053         pw.print(mProcessList.getMemLevel(adj)/1024);
   11054         pw.println(" kB)");
   11055     }
   11056 
   11057     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11058             int opti, boolean dumpAll) {
   11059         boolean needSep = false;
   11060 
   11061         if (mLruProcesses.size() > 0) {
   11062             if (needSep) pw.println();
   11063             needSep = true;
   11064             pw.println("  OOM levels:");
   11065             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   11066             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   11067             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   11068             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   11069             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   11070             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   11071             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   11072             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   11073             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   11074             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   11075             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   11076             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   11077             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   11078 
   11079             if (needSep) pw.println();
   11080             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   11081                     pw.print(" total, non-act at ");
   11082                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   11083                     pw.print(", non-svc at ");
   11084                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   11085                     pw.println("):");
   11086             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   11087             needSep = true;
   11088         }
   11089 
   11090         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   11091 
   11092         pw.println();
   11093         pw.println("  mHomeProcess: " + mHomeProcess);
   11094         pw.println("  mPreviousProcess: " + mPreviousProcess);
   11095         if (mHeavyWeightProcess != null) {
   11096             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   11097         }
   11098 
   11099         return true;
   11100     }
   11101 
   11102     /**
   11103      * There are three ways to call this:
   11104      *  - no provider specified: dump all the providers
   11105      *  - a flattened component name that matched an existing provider was specified as the
   11106      *    first arg: dump that one provider
   11107      *  - the first arg isn't the flattened component name of an existing provider:
   11108      *    dump all providers whose component contains the first arg as a substring
   11109      */
   11110     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   11111             int opti, boolean dumpAll) {
   11112         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   11113     }
   11114 
   11115     static class ItemMatcher {
   11116         ArrayList<ComponentName> components;
   11117         ArrayList<String> strings;
   11118         ArrayList<Integer> objects;
   11119         boolean all;
   11120 
   11121         ItemMatcher() {
   11122             all = true;
   11123         }
   11124 
   11125         void build(String name) {
   11126             ComponentName componentName = ComponentName.unflattenFromString(name);
   11127             if (componentName != null) {
   11128                 if (components == null) {
   11129                     components = new ArrayList<ComponentName>();
   11130                 }
   11131                 components.add(componentName);
   11132                 all = false;
   11133             } else {
   11134                 int objectId = 0;
   11135                 // Not a '/' separated full component name; maybe an object ID?
   11136                 try {
   11137                     objectId = Integer.parseInt(name, 16);
   11138                     if (objects == null) {
   11139                         objects = new ArrayList<Integer>();
   11140                     }
   11141                     objects.add(objectId);
   11142                     all = false;
   11143                 } catch (RuntimeException e) {
   11144                     // Not an integer; just do string match.
   11145                     if (strings == null) {
   11146                         strings = new ArrayList<String>();
   11147                     }
   11148                     strings.add(name);
   11149                     all = false;
   11150                 }
   11151             }
   11152         }
   11153 
   11154         int build(String[] args, int opti) {
   11155             for (; opti<args.length; opti++) {
   11156                 String name = args[opti];
   11157                 if ("--".equals(name)) {
   11158                     return opti+1;
   11159                 }
   11160                 build(name);
   11161             }
   11162             return opti;
   11163         }
   11164 
   11165         boolean match(Object object, ComponentName comp) {
   11166             if (all) {
   11167                 return true;
   11168             }
   11169             if (components != null) {
   11170                 for (int i=0; i<components.size(); i++) {
   11171                     if (components.get(i).equals(comp)) {
   11172                         return true;
   11173                     }
   11174                 }
   11175             }
   11176             if (objects != null) {
   11177                 for (int i=0; i<objects.size(); i++) {
   11178                     if (System.identityHashCode(object) == objects.get(i)) {
   11179                         return true;
   11180                     }
   11181                 }
   11182             }
   11183             if (strings != null) {
   11184                 String flat = comp.flattenToString();
   11185                 for (int i=0; i<strings.size(); i++) {
   11186                     if (flat.contains(strings.get(i))) {
   11187                         return true;
   11188                     }
   11189                 }
   11190             }
   11191             return false;
   11192         }
   11193     }
   11194 
   11195     /**
   11196      * There are three things that cmd can be:
   11197      *  - a flattened component name that matches an existing activity
   11198      *  - the cmd arg isn't the flattened component name of an existing activity:
   11199      *    dump all activity whose component contains the cmd as a substring
   11200      *  - A hex number of the ActivityRecord object instance.
   11201      */
   11202     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   11203             int opti, boolean dumpAll) {
   11204         ArrayList<ActivityRecord> activities;
   11205 
   11206         synchronized (this) {
   11207             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   11208         }
   11209 
   11210         if (activities.size() <= 0) {
   11211             return false;
   11212         }
   11213 
   11214         String[] newArgs = new String[args.length - opti];
   11215         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   11216 
   11217         TaskRecord lastTask = null;
   11218         boolean needSep = false;
   11219         for (int i=activities.size()-1; i>=0; i--) {
   11220             ActivityRecord r = activities.get(i);
   11221             if (needSep) {
   11222                 pw.println();
   11223             }
   11224             needSep = true;
   11225             synchronized (this) {
   11226                 if (lastTask != r.task) {
   11227                     lastTask = r.task;
   11228                     pw.print("TASK "); pw.print(lastTask.affinity);
   11229                             pw.print(" id="); pw.println(lastTask.taskId);
   11230                     if (dumpAll) {
   11231                         lastTask.dump(pw, "  ");
   11232                     }
   11233                 }
   11234             }
   11235             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   11236         }
   11237         return true;
   11238     }
   11239 
   11240     /**
   11241      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   11242      * there is a thread associated with the activity.
   11243      */
   11244     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   11245             final ActivityRecord r, String[] args, boolean dumpAll) {
   11246         String innerPrefix = prefix + "  ";
   11247         synchronized (this) {
   11248             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   11249                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   11250                     pw.print(" pid=");
   11251                     if (r.app != null) pw.println(r.app.pid);
   11252                     else pw.println("(not running)");
   11253             if (dumpAll) {
   11254                 r.dump(pw, innerPrefix);
   11255             }
   11256         }
   11257         if (r.app != null && r.app.thread != null) {
   11258             // flush anything that is already in the PrintWriter since the thread is going
   11259             // to write to the file descriptor directly
   11260             pw.flush();
   11261             try {
   11262                 TransferPipe tp = new TransferPipe();
   11263                 try {
   11264                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   11265                             r.appToken, innerPrefix, args);
   11266                     tp.go(fd);
   11267                 } finally {
   11268                     tp.kill();
   11269                 }
   11270             } catch (IOException e) {
   11271                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   11272             } catch (RemoteException e) {
   11273                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   11274             }
   11275         }
   11276     }
   11277 
   11278     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11279             int opti, boolean dumpAll, String dumpPackage) {
   11280         boolean needSep = false;
   11281         boolean onlyHistory = false;
   11282         boolean printedAnything = false;
   11283 
   11284         if ("history".equals(dumpPackage)) {
   11285             if (opti < args.length && "-s".equals(args[opti])) {
   11286                 dumpAll = false;
   11287             }
   11288             onlyHistory = true;
   11289             dumpPackage = null;
   11290         }
   11291 
   11292         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   11293         if (!onlyHistory && dumpAll) {
   11294             if (mRegisteredReceivers.size() > 0) {
   11295                 boolean printed = false;
   11296                 Iterator it = mRegisteredReceivers.values().iterator();
   11297                 while (it.hasNext()) {
   11298                     ReceiverList r = (ReceiverList)it.next();
   11299                     if (dumpPackage != null && (r.app == null ||
   11300                             !dumpPackage.equals(r.app.info.packageName))) {
   11301                         continue;
   11302                     }
   11303                     if (!printed) {
   11304                         pw.println("  Registered Receivers:");
   11305                         needSep = true;
   11306                         printed = true;
   11307                         printedAnything = true;
   11308                     }
   11309                     pw.print("  * "); pw.println(r);
   11310                     r.dump(pw, "    ");
   11311                 }
   11312             }
   11313 
   11314             if (mReceiverResolver.dump(pw, needSep ?
   11315                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   11316                     "    ", dumpPackage, false)) {
   11317                 needSep = true;
   11318                 printedAnything = true;
   11319             }
   11320         }
   11321 
   11322         for (BroadcastQueue q : mBroadcastQueues) {
   11323             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   11324             printedAnything |= needSep;
   11325         }
   11326 
   11327         needSep = true;
   11328 
   11329         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   11330             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   11331                 if (needSep) {
   11332                     pw.println();
   11333                 }
   11334                 needSep = true;
   11335                 printedAnything = true;
   11336                 pw.print("  Sticky broadcasts for user ");
   11337                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   11338                 StringBuilder sb = new StringBuilder(128);
   11339                 for (Map.Entry<String, ArrayList<Intent>> ent
   11340                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   11341                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   11342                     if (dumpAll) {
   11343                         pw.println(":");
   11344                         ArrayList<Intent> intents = ent.getValue();
   11345                         final int N = intents.size();
   11346                         for (int i=0; i<N; i++) {
   11347                             sb.setLength(0);
   11348                             sb.append("    Intent: ");
   11349                             intents.get(i).toShortString(sb, false, true, false, false);
   11350                             pw.println(sb.toString());
   11351                             Bundle bundle = intents.get(i).getExtras();
   11352                             if (bundle != null) {
   11353                                 pw.print("      ");
   11354                                 pw.println(bundle.toString());
   11355                             }
   11356                         }
   11357                     } else {
   11358                         pw.println("");
   11359                     }
   11360                 }
   11361             }
   11362         }
   11363 
   11364         if (!onlyHistory && dumpAll) {
   11365             pw.println();
   11366             for (BroadcastQueue queue : mBroadcastQueues) {
   11367                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   11368                         + queue.mBroadcastsScheduled);
   11369             }
   11370             pw.println("  mHandler:");
   11371             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   11372             needSep = true;
   11373             printedAnything = true;
   11374         }
   11375 
   11376         if (!printedAnything) {
   11377             pw.println("  (nothing)");
   11378         }
   11379     }
   11380 
   11381     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11382             int opti, boolean dumpAll, String dumpPackage) {
   11383         boolean needSep;
   11384         boolean printedAnything = false;
   11385 
   11386         ItemMatcher matcher = new ItemMatcher();
   11387         matcher.build(args, opti);
   11388 
   11389         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   11390 
   11391         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   11392         printedAnything |= needSep;
   11393 
   11394         if (mLaunchingProviders.size() > 0) {
   11395             boolean printed = false;
   11396             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   11397                 ContentProviderRecord r = mLaunchingProviders.get(i);
   11398                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   11399                     continue;
   11400                 }
   11401                 if (!printed) {
   11402                     if (needSep) pw.println();
   11403                     needSep = true;
   11404                     pw.println("  Launching content providers:");
   11405                     printed = true;
   11406                     printedAnything = true;
   11407                 }
   11408                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   11409                         pw.println(r);
   11410             }
   11411         }
   11412 
   11413         if (mGrantedUriPermissions.size() > 0) {
   11414             boolean printed = false;
   11415             int dumpUid = -2;
   11416             if (dumpPackage != null) {
   11417                 try {
   11418                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   11419                 } catch (NameNotFoundException e) {
   11420                     dumpUid = -1;
   11421                 }
   11422             }
   11423             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   11424                 int uid = mGrantedUriPermissions.keyAt(i);
   11425                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   11426                     continue;
   11427                 }
   11428                 ArrayMap<Uri, UriPermission> perms
   11429                         = mGrantedUriPermissions.valueAt(i);
   11430                 if (!printed) {
   11431                     if (needSep) pw.println();
   11432                     needSep = true;
   11433                     pw.println("  Granted Uri Permissions:");
   11434                     printed = true;
   11435                     printedAnything = true;
   11436                 }
   11437                 pw.print("  * UID "); pw.print(uid);
   11438                         pw.println(" holds:");
   11439                 for (UriPermission perm : perms.values()) {
   11440                     pw.print("    "); pw.println(perm);
   11441                     if (dumpAll) {
   11442                         perm.dump(pw, "      ");
   11443                     }
   11444                 }
   11445             }
   11446         }
   11447 
   11448         if (!printedAnything) {
   11449             pw.println("  (nothing)");
   11450         }
   11451     }
   11452 
   11453     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11454             int opti, boolean dumpAll, String dumpPackage) {
   11455         boolean printed = false;
   11456 
   11457         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   11458 
   11459         if (mIntentSenderRecords.size() > 0) {
   11460             Iterator<WeakReference<PendingIntentRecord>> it
   11461                     = mIntentSenderRecords.values().iterator();
   11462             while (it.hasNext()) {
   11463                 WeakReference<PendingIntentRecord> ref = it.next();
   11464                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   11465                 if (dumpPackage != null && (rec == null
   11466                         || !dumpPackage.equals(rec.key.packageName))) {
   11467                     continue;
   11468                 }
   11469                 printed = true;
   11470                 if (rec != null) {
   11471                     pw.print("  * "); pw.println(rec);
   11472                     if (dumpAll) {
   11473                         rec.dump(pw, "    ");
   11474                     }
   11475                 } else {
   11476                     pw.print("  * "); pw.println(ref);
   11477                 }
   11478             }
   11479         }
   11480 
   11481         if (!printed) {
   11482             pw.println("  (nothing)");
   11483         }
   11484     }
   11485 
   11486     private static final int dumpProcessList(PrintWriter pw,
   11487             ActivityManagerService service, List list,
   11488             String prefix, String normalLabel, String persistentLabel,
   11489             String dumpPackage) {
   11490         int numPers = 0;
   11491         final int N = list.size()-1;
   11492         for (int i=N; i>=0; i--) {
   11493             ProcessRecord r = (ProcessRecord)list.get(i);
   11494             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   11495                 continue;
   11496             }
   11497             pw.println(String.format("%s%s #%2d: %s",
   11498                     prefix, (r.persistent ? persistentLabel : normalLabel),
   11499                     i, r.toString()));
   11500             if (r.persistent) {
   11501                 numPers++;
   11502             }
   11503         }
   11504         return numPers;
   11505     }
   11506 
   11507     private static final boolean dumpProcessOomList(PrintWriter pw,
   11508             ActivityManagerService service, List<ProcessRecord> origList,
   11509             String prefix, String normalLabel, String persistentLabel,
   11510             boolean inclDetails, String dumpPackage) {
   11511 
   11512         ArrayList<Pair<ProcessRecord, Integer>> list
   11513                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   11514         for (int i=0; i<origList.size(); i++) {
   11515             ProcessRecord r = origList.get(i);
   11516             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   11517                 continue;
   11518             }
   11519             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   11520         }
   11521 
   11522         if (list.size() <= 0) {
   11523             return false;
   11524         }
   11525 
   11526         Comparator<Pair<ProcessRecord, Integer>> comparator
   11527                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   11528             @Override
   11529             public int compare(Pair<ProcessRecord, Integer> object1,
   11530                     Pair<ProcessRecord, Integer> object2) {
   11531                 if (object1.first.setAdj != object2.first.setAdj) {
   11532                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   11533                 }
   11534                 if (object1.second.intValue() != object2.second.intValue()) {
   11535                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   11536                 }
   11537                 return 0;
   11538             }
   11539         };
   11540 
   11541         Collections.sort(list, comparator);
   11542 
   11543         final long curRealtime = SystemClock.elapsedRealtime();
   11544         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   11545         final long curUptime = SystemClock.uptimeMillis();
   11546         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   11547 
   11548         for (int i=list.size()-1; i>=0; i--) {
   11549             ProcessRecord r = list.get(i).first;
   11550             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   11551             char schedGroup;
   11552             switch (r.setSchedGroup) {
   11553                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   11554                     schedGroup = 'B';
   11555                     break;
   11556                 case Process.THREAD_GROUP_DEFAULT:
   11557                     schedGroup = 'F';
   11558                     break;
   11559                 default:
   11560                     schedGroup = '?';
   11561                     break;
   11562             }
   11563             char foreground;
   11564             if (r.foregroundActivities) {
   11565                 foreground = 'A';
   11566             } else if (r.foregroundServices) {
   11567                 foreground = 'S';
   11568             } else {
   11569                 foreground = ' ';
   11570             }
   11571             String procState = ProcessList.makeProcStateString(r.curProcState);
   11572             pw.print(prefix);
   11573             pw.print(r.persistent ? persistentLabel : normalLabel);
   11574             pw.print(" #");
   11575             int num = (origList.size()-1)-list.get(i).second;
   11576             if (num < 10) pw.print(' ');
   11577             pw.print(num);
   11578             pw.print(": ");
   11579             pw.print(oomAdj);
   11580             pw.print(' ');
   11581             pw.print(schedGroup);
   11582             pw.print('/');
   11583             pw.print(foreground);
   11584             pw.print('/');
   11585             pw.print(procState);
   11586             pw.print(" trm:");
   11587             if (r.trimMemoryLevel < 10) pw.print(' ');
   11588             pw.print(r.trimMemoryLevel);
   11589             pw.print(' ');
   11590             pw.print(r.toShortString());
   11591             pw.print(" (");
   11592             pw.print(r.adjType);
   11593             pw.println(')');
   11594             if (r.adjSource != null || r.adjTarget != null) {
   11595                 pw.print(prefix);
   11596                 pw.print("    ");
   11597                 if (r.adjTarget instanceof ComponentName) {
   11598                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   11599                 } else if (r.adjTarget != null) {
   11600                     pw.print(r.adjTarget.toString());
   11601                 } else {
   11602                     pw.print("{null}");
   11603                 }
   11604                 pw.print("<=");
   11605                 if (r.adjSource instanceof ProcessRecord) {
   11606                     pw.print("Proc{");
   11607                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   11608                     pw.println("}");
   11609                 } else if (r.adjSource != null) {
   11610                     pw.println(r.adjSource.toString());
   11611                 } else {
   11612                     pw.println("{null}");
   11613                 }
   11614             }
   11615             if (inclDetails) {
   11616                 pw.print(prefix);
   11617                 pw.print("    ");
   11618                 pw.print("oom: max="); pw.print(r.maxAdj);
   11619                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   11620                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   11621                 pw.print(" cur="); pw.print(r.curAdj);
   11622                 pw.print(" set="); pw.println(r.setAdj);
   11623                 pw.print(prefix);
   11624                 pw.print("    ");
   11625                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   11626                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   11627                 pw.print(" lastPss="); pw.print(r.lastPss);
   11628                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   11629                 pw.print(prefix);
   11630                 pw.print("    ");
   11631                 pw.print("keeping="); pw.print(r.keeping);
   11632                 pw.print(" cached="); pw.print(r.cached);
   11633                 pw.print(" empty="); pw.print(r.empty);
   11634                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   11635 
   11636                 if (!r.keeping) {
   11637                     if (r.lastWakeTime != 0) {
   11638                         long wtime;
   11639                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   11640                         synchronized (stats) {
   11641                             wtime = stats.getProcessWakeTime(r.info.uid,
   11642                                     r.pid, curRealtime);
   11643                         }
   11644                         long timeUsed = wtime - r.lastWakeTime;
   11645                         pw.print(prefix);
   11646                         pw.print("    ");
   11647                         pw.print("keep awake over ");
   11648                         TimeUtils.formatDuration(realtimeSince, pw);
   11649                         pw.print(" used ");
   11650                         TimeUtils.formatDuration(timeUsed, pw);
   11651                         pw.print(" (");
   11652                         pw.print((timeUsed*100)/realtimeSince);
   11653                         pw.println("%)");
   11654                     }
   11655                     if (r.lastCpuTime != 0) {
   11656                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   11657                         pw.print(prefix);
   11658                         pw.print("    ");
   11659                         pw.print("run cpu over ");
   11660                         TimeUtils.formatDuration(uptimeSince, pw);
   11661                         pw.print(" used ");
   11662                         TimeUtils.formatDuration(timeUsed, pw);
   11663                         pw.print(" (");
   11664                         pw.print((timeUsed*100)/uptimeSince);
   11665                         pw.println("%)");
   11666                     }
   11667                 }
   11668             }
   11669         }
   11670         return true;
   11671     }
   11672 
   11673     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   11674         ArrayList<ProcessRecord> procs;
   11675         synchronized (this) {
   11676             if (args != null && args.length > start
   11677                     && args[start].charAt(0) != '-') {
   11678                 procs = new ArrayList<ProcessRecord>();
   11679                 int pid = -1;
   11680                 try {
   11681                     pid = Integer.parseInt(args[start]);
   11682                 } catch (NumberFormatException e) {
   11683                 }
   11684                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   11685                     ProcessRecord proc = mLruProcesses.get(i);
   11686                     if (proc.pid == pid) {
   11687                         procs.add(proc);
   11688                     } else if (proc.processName.equals(args[start])) {
   11689                         procs.add(proc);
   11690                     }
   11691                 }
   11692                 if (procs.size() <= 0) {
   11693                     return null;
   11694                 }
   11695             } else {
   11696                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   11697             }
   11698         }
   11699         return procs;
   11700     }
   11701 
   11702     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   11703             PrintWriter pw, String[] args) {
   11704         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11705         if (procs == null) {
   11706             pw.println("No process found for: " + args[0]);
   11707             return;
   11708         }
   11709 
   11710         long uptime = SystemClock.uptimeMillis();
   11711         long realtime = SystemClock.elapsedRealtime();
   11712         pw.println("Applications Graphics Acceleration Info:");
   11713         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11714 
   11715         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11716             ProcessRecord r = procs.get(i);
   11717             if (r.thread != null) {
   11718                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   11719                 pw.flush();
   11720                 try {
   11721                     TransferPipe tp = new TransferPipe();
   11722                     try {
   11723                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   11724                         tp.go(fd);
   11725                     } finally {
   11726                         tp.kill();
   11727                     }
   11728                 } catch (IOException e) {
   11729                     pw.println("Failure while dumping the app: " + r);
   11730                     pw.flush();
   11731                 } catch (RemoteException e) {
   11732                     pw.println("Got a RemoteException while dumping the app " + r);
   11733                     pw.flush();
   11734                 }
   11735             }
   11736         }
   11737     }
   11738 
   11739     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   11740         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11741         if (procs == null) {
   11742             pw.println("No process found for: " + args[0]);
   11743             return;
   11744         }
   11745 
   11746         pw.println("Applications Database Info:");
   11747 
   11748         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11749             ProcessRecord r = procs.get(i);
   11750             if (r.thread != null) {
   11751                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   11752                 pw.flush();
   11753                 try {
   11754                     TransferPipe tp = new TransferPipe();
   11755                     try {
   11756                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   11757                         tp.go(fd);
   11758                     } finally {
   11759                         tp.kill();
   11760                     }
   11761                 } catch (IOException e) {
   11762                     pw.println("Failure while dumping the app: " + r);
   11763                     pw.flush();
   11764                 } catch (RemoteException e) {
   11765                     pw.println("Got a RemoteException while dumping the app " + r);
   11766                     pw.flush();
   11767                 }
   11768             }
   11769         }
   11770     }
   11771 
   11772     final static class MemItem {
   11773         final boolean isProc;
   11774         final String label;
   11775         final String shortLabel;
   11776         final long pss;
   11777         final int id;
   11778         final boolean hasActivities;
   11779         ArrayList<MemItem> subitems;
   11780 
   11781         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   11782                 boolean _hasActivities) {
   11783             isProc = true;
   11784             label = _label;
   11785             shortLabel = _shortLabel;
   11786             pss = _pss;
   11787             id = _id;
   11788             hasActivities = _hasActivities;
   11789         }
   11790 
   11791         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   11792             isProc = false;
   11793             label = _label;
   11794             shortLabel = _shortLabel;
   11795             pss = _pss;
   11796             id = _id;
   11797             hasActivities = false;
   11798         }
   11799     }
   11800 
   11801     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   11802             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   11803         if (sort && !isCompact) {
   11804             Collections.sort(items, new Comparator<MemItem>() {
   11805                 @Override
   11806                 public int compare(MemItem lhs, MemItem rhs) {
   11807                     if (lhs.pss < rhs.pss) {
   11808                         return 1;
   11809                     } else if (lhs.pss > rhs.pss) {
   11810                         return -1;
   11811                     }
   11812                     return 0;
   11813                 }
   11814             });
   11815         }
   11816 
   11817         for (int i=0; i<items.size(); i++) {
   11818             MemItem mi = items.get(i);
   11819             if (!isCompact) {
   11820                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   11821             } else if (mi.isProc) {
   11822                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   11823                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   11824                 pw.println(mi.hasActivities ? ",a" : ",e");
   11825             } else {
   11826                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   11827                 pw.println(mi.pss);
   11828             }
   11829             if (mi.subitems != null) {
   11830                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   11831                         true, isCompact);
   11832             }
   11833         }
   11834     }
   11835 
   11836     // These are in KB.
   11837     static final long[] DUMP_MEM_BUCKETS = new long[] {
   11838         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   11839         120*1024, 160*1024, 200*1024,
   11840         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   11841         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   11842     };
   11843 
   11844     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   11845             boolean stackLike) {
   11846         int start = label.lastIndexOf('.');
   11847         if (start >= 0) start++;
   11848         else start = 0;
   11849         int end = label.length();
   11850         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   11851             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   11852                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   11853                 out.append(bucket);
   11854                 out.append(stackLike ? "MB." : "MB ");
   11855                 out.append(label, start, end);
   11856                 return;
   11857             }
   11858         }
   11859         out.append(memKB/1024);
   11860         out.append(stackLike ? "MB." : "MB ");
   11861         out.append(label, start, end);
   11862     }
   11863 
   11864     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   11865             ProcessList.NATIVE_ADJ,
   11866             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   11867             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   11868             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   11869             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   11870             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   11871     };
   11872     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   11873             "Native",
   11874             "System", "Persistent", "Foreground",
   11875             "Visible", "Perceptible",
   11876             "Heavy Weight", "Backup",
   11877             "A Services", "Home",
   11878             "Previous", "B Services", "Cached"
   11879     };
   11880     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   11881             "native",
   11882             "sys", "pers", "fore",
   11883             "vis", "percept",
   11884             "heavy", "backup",
   11885             "servicea", "home",
   11886             "prev", "serviceb", "cached"
   11887     };
   11888 
   11889     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   11890             long realtime, boolean isCheckinRequest, boolean isCompact) {
   11891         if (isCheckinRequest || isCompact) {
   11892             // short checkin version
   11893             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   11894         } else {
   11895             pw.println("Applications Memory Usage (kB):");
   11896             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11897         }
   11898     }
   11899 
   11900     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   11901             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   11902         boolean dumpDetails = false;
   11903         boolean dumpFullDetails = false;
   11904         boolean dumpDalvik = false;
   11905         boolean oomOnly = false;
   11906         boolean isCompact = false;
   11907         boolean localOnly = false;
   11908 
   11909         int opti = 0;
   11910         while (opti < args.length) {
   11911             String opt = args[opti];
   11912             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   11913                 break;
   11914             }
   11915             opti++;
   11916             if ("-a".equals(opt)) {
   11917                 dumpDetails = true;
   11918                 dumpFullDetails = true;
   11919                 dumpDalvik = true;
   11920             } else if ("-d".equals(opt)) {
   11921                 dumpDalvik = true;
   11922             } else if ("-c".equals(opt)) {
   11923                 isCompact = true;
   11924             } else if ("--oom".equals(opt)) {
   11925                 oomOnly = true;
   11926             } else if ("--local".equals(opt)) {
   11927                 localOnly = true;
   11928             } else if ("-h".equals(opt)) {
   11929                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   11930                 pw.println("  -a: include all available information for each process.");
   11931                 pw.println("  -d: include dalvik details when dumping process details.");
   11932                 pw.println("  -c: dump in a compact machine-parseable representation.");
   11933                 pw.println("  --oom: only show processes organized by oom adj.");
   11934                 pw.println("  --local: only collect details locally, don't call process.");
   11935                 pw.println("If [process] is specified it can be the name or ");
   11936                 pw.println("pid of a specific process to dump.");
   11937                 return;
   11938             } else {
   11939                 pw.println("Unknown argument: " + opt + "; use -h for help");
   11940             }
   11941         }
   11942 
   11943         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   11944         long uptime = SystemClock.uptimeMillis();
   11945         long realtime = SystemClock.elapsedRealtime();
   11946         final long[] tmpLong = new long[1];
   11947 
   11948         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   11949         if (procs == null) {
   11950             // No Java processes.  Maybe they want to print a native process.
   11951             if (args != null && args.length > opti
   11952                     && args[opti].charAt(0) != '-') {
   11953                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   11954                         = new ArrayList<ProcessCpuTracker.Stats>();
   11955                 updateCpuStatsNow();
   11956                 int findPid = -1;
   11957                 try {
   11958                     findPid = Integer.parseInt(args[opti]);
   11959                 } catch (NumberFormatException e) {
   11960                 }
   11961                 synchronized (mProcessCpuThread) {
   11962                     final int N = mProcessCpuTracker.countStats();
   11963                     for (int i=0; i<N; i++) {
   11964                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   11965                         if (st.pid == findPid || (st.baseName != null
   11966                                 && st.baseName.equals(args[opti]))) {
   11967                             nativeProcs.add(st);
   11968                         }
   11969                     }
   11970                 }
   11971                 if (nativeProcs.size() > 0) {
   11972                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   11973                             isCompact);
   11974                     Debug.MemoryInfo mi = null;
   11975                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   11976                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   11977                         final int pid = r.pid;
   11978                         if (!isCheckinRequest && dumpDetails) {
   11979                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   11980                         }
   11981                         if (mi == null) {
   11982                             mi = new Debug.MemoryInfo();
   11983                         }
   11984                         if (dumpDetails || (!brief && !oomOnly)) {
   11985                             Debug.getMemoryInfo(pid, mi);
   11986                         } else {
   11987                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   11988                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   11989                         }
   11990                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   11991                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   11992                         if (isCheckinRequest) {
   11993                             pw.println();
   11994                         }
   11995                     }
   11996                     return;
   11997                 }
   11998             }
   11999             pw.println("No process found for: " + args[opti]);
   12000             return;
   12001         }
   12002 
   12003         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
   12004             dumpDetails = true;
   12005         }
   12006 
   12007         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   12008 
   12009         String[] innerArgs = new String[args.length-opti];
   12010         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   12011 
   12012         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   12013         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   12014         long nativePss=0, dalvikPss=0, otherPss=0;
   12015         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   12016 
   12017         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   12018         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   12019                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   12020 
   12021         long totalPss = 0;
   12022         long cachedPss = 0;
   12023 
   12024         Debug.MemoryInfo mi = null;
   12025         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   12026             final ProcessRecord r = procs.get(i);
   12027             final IApplicationThread thread;
   12028             final int pid;
   12029             final int oomAdj;
   12030             final boolean hasActivities;
   12031             synchronized (this) {
   12032                 thread = r.thread;
   12033                 pid = r.pid;
   12034                 oomAdj = r.getSetAdjWithServices();
   12035                 hasActivities = r.activities.size() > 0;
   12036             }
   12037             if (thread != null) {
   12038                 if (!isCheckinRequest && dumpDetails) {
   12039                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   12040                 }
   12041                 if (mi == null) {
   12042                     mi = new Debug.MemoryInfo();
   12043                 }
   12044                 if (dumpDetails || (!brief && !oomOnly)) {
   12045                     Debug.getMemoryInfo(pid, mi);
   12046                 } else {
   12047                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   12048                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   12049                 }
   12050                 if (dumpDetails) {
   12051                     if (localOnly) {
   12052                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   12053                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
   12054                         if (isCheckinRequest) {
   12055                             pw.println();
   12056                         }
   12057                     } else {
   12058                         try {
   12059                             pw.flush();
   12060                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   12061                                     dumpDalvik, innerArgs);
   12062                         } catch (RemoteException e) {
   12063                             if (!isCheckinRequest) {
   12064                                 pw.println("Got RemoteException!");
   12065                                 pw.flush();
   12066                             }
   12067                         }
   12068                     }
   12069                 }
   12070 
   12071                 final long myTotalPss = mi.getTotalPss();
   12072                 final long myTotalUss = mi.getTotalUss();
   12073 
   12074                 synchronized (this) {
   12075                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   12076                         // Record this for posterity if the process has been stable.
   12077                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   12078                     }
   12079                 }
   12080 
   12081                 if (!isCheckinRequest && mi != null) {
   12082                     totalPss += myTotalPss;
   12083                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   12084                             (hasActivities ? " / activities)" : ")"),
   12085                             r.processName, myTotalPss, pid, hasActivities);
   12086                     procMems.add(pssItem);
   12087                     procMemsMap.put(pid, pssItem);
   12088 
   12089                     nativePss += mi.nativePss;
   12090                     dalvikPss += mi.dalvikPss;
   12091                     otherPss += mi.otherPss;
   12092                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12093                         long mem = mi.getOtherPss(j);
   12094                         miscPss[j] += mem;
   12095                         otherPss -= mem;
   12096                     }
   12097 
   12098                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   12099                         cachedPss += myTotalPss;
   12100                     }
   12101 
   12102                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   12103                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   12104                                 || oomIndex == (oomPss.length-1)) {
   12105                             oomPss[oomIndex] += myTotalPss;
   12106                             if (oomProcs[oomIndex] == null) {
   12107                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   12108                             }
   12109                             oomProcs[oomIndex].add(pssItem);
   12110                             break;
   12111                         }
   12112                     }
   12113                 }
   12114             }
   12115         }
   12116 
   12117         if (!isCheckinRequest && procs.size() > 1) {
   12118             // If we are showing aggregations, also look for native processes to
   12119             // include so that our aggregations are more accurate.
   12120             updateCpuStatsNow();
   12121             synchronized (mProcessCpuThread) {
   12122                 final int N = mProcessCpuTracker.countStats();
   12123                 for (int i=0; i<N; i++) {
   12124                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   12125                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   12126                         if (mi == null) {
   12127                             mi = new Debug.MemoryInfo();
   12128                         }
   12129                         if (!brief && !oomOnly) {
   12130                             Debug.getMemoryInfo(st.pid, mi);
   12131                         } else {
   12132                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
   12133                             mi.nativePrivateDirty = (int)tmpLong[0];
   12134                         }
   12135 
   12136                         final long myTotalPss = mi.getTotalPss();
   12137                         totalPss += myTotalPss;
   12138 
   12139                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   12140                                 st.name, myTotalPss, st.pid, false);
   12141                         procMems.add(pssItem);
   12142 
   12143                         nativePss += mi.nativePss;
   12144                         dalvikPss += mi.dalvikPss;
   12145                         otherPss += mi.otherPss;
   12146                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12147                             long mem = mi.getOtherPss(j);
   12148                             miscPss[j] += mem;
   12149                             otherPss -= mem;
   12150                         }
   12151                         oomPss[0] += myTotalPss;
   12152                         if (oomProcs[0] == null) {
   12153                             oomProcs[0] = new ArrayList<MemItem>();
   12154                         }
   12155                         oomProcs[0].add(pssItem);
   12156                     }
   12157                 }
   12158             }
   12159 
   12160             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   12161 
   12162             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   12163             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   12164             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   12165             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12166                 String label = Debug.MemoryInfo.getOtherLabel(j);
   12167                 catMems.add(new MemItem(label, label, miscPss[j], j));
   12168             }
   12169 
   12170             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   12171             for (int j=0; j<oomPss.length; j++) {
   12172                 if (oomPss[j] != 0) {
   12173                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   12174                             : DUMP_MEM_OOM_LABEL[j];
   12175                     MemItem item = new MemItem(label, label, oomPss[j],
   12176                             DUMP_MEM_OOM_ADJ[j]);
   12177                     item.subitems = oomProcs[j];
   12178                     oomMems.add(item);
   12179                 }
   12180             }
   12181 
   12182             if (!brief && !oomOnly && !isCompact) {
   12183                 pw.println();
   12184                 pw.println("Total PSS by process:");
   12185                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   12186                 pw.println();
   12187             }
   12188             if (!isCompact) {
   12189                 pw.println("Total PSS by OOM adjustment:");
   12190             }
   12191             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   12192             if (!brief && !oomOnly) {
   12193                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   12194                 if (!isCompact) {
   12195                     out.println();
   12196                     out.println("Total PSS by category:");
   12197                 }
   12198                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   12199             }
   12200             if (!isCompact) {
   12201                 pw.println();
   12202             }
   12203             MemInfoReader memInfo = new MemInfoReader();
   12204             memInfo.readMemInfo();
   12205             if (!brief) {
   12206                 if (!isCompact) {
   12207                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   12208                     pw.println(" kB");
   12209                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   12210                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   12211                             pw.print(cachedPss); pw.print(" cached pss + ");
   12212                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
   12213                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   12214                 } else {
   12215                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   12216                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   12217                             + memInfo.getFreeSizeKb()); pw.print(",");
   12218                     pw.println(totalPss - cachedPss);
   12219                 }
   12220             }
   12221             if (!isCompact) {
   12222                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   12223                         + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
   12224                         + memInfo.getSlabSizeKb()); pw.print(" kB (");
   12225                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   12226                         pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
   12227                         pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
   12228                         pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
   12229                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   12230                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   12231                         - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
   12232                         - memInfo.getSlabSizeKb()); pw.println(" kB");
   12233             }
   12234             if (!brief) {
   12235                 if (memInfo.getZramTotalSizeKb() != 0) {
   12236                     if (!isCompact) {
   12237                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   12238                                 pw.print(" kB physical used for ");
   12239                                 pw.print(memInfo.getSwapTotalSizeKb()
   12240                                         - memInfo.getSwapFreeSizeKb());
   12241                                 pw.print(" kB in swap (");
   12242                                 pw.print(memInfo.getSwapTotalSizeKb());
   12243                                 pw.println(" kB total swap)");
   12244                     } else {
   12245                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   12246                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   12247                                 pw.println(memInfo.getSwapFreeSizeKb());
   12248                     }
   12249                 }
   12250                 final int[] SINGLE_LONG_FORMAT = new int[] {
   12251                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   12252                 };
   12253                 long[] longOut = new long[1];
   12254                 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   12255                         SINGLE_LONG_FORMAT, null, longOut, null);
   12256                 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12257                 longOut[0] = 0;
   12258                 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   12259                         SINGLE_LONG_FORMAT, null, longOut, null);
   12260                 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12261                 longOut[0] = 0;
   12262                 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   12263                         SINGLE_LONG_FORMAT, null, longOut, null);
   12264                 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12265                 longOut[0] = 0;
   12266                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   12267                         SINGLE_LONG_FORMAT, null, longOut, null);
   12268                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12269                 if (!isCompact) {
   12270                     if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
   12271                         pw.print("      KSM: "); pw.print(sharing);
   12272                                 pw.print(" kB saved from shared ");
   12273                                 pw.print(shared); pw.println(" kB");
   12274                         pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   12275                                 pw.print(voltile); pw.println(" kB volatile");
   12276                     }
   12277                     pw.print("   Tuning: ");
   12278                     pw.print(ActivityManager.staticGetMemoryClass());
   12279                     pw.print(" (large ");
   12280                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12281                     pw.print("), oom ");
   12282                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12283                     pw.print(" kB");
   12284                     pw.print(", restore limit ");
   12285                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   12286                     pw.print(" kB");
   12287                     if (ActivityManager.isLowRamDeviceStatic()) {
   12288                         pw.print(" (low-ram)");
   12289                     }
   12290                     if (ActivityManager.isHighEndGfx()) {
   12291                         pw.print(" (high-end-gfx)");
   12292                     }
   12293                     pw.println();
   12294                 } else {
   12295                     pw.print("ksm,"); pw.print(sharing); pw.print(",");
   12296                     pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
   12297                     pw.println(voltile);
   12298                     pw.print("tuning,");
   12299                     pw.print(ActivityManager.staticGetMemoryClass());
   12300                     pw.print(',');
   12301                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12302                     pw.print(',');
   12303                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12304                     if (ActivityManager.isLowRamDeviceStatic()) {
   12305                         pw.print(",low-ram");
   12306                     }
   12307                     if (ActivityManager.isHighEndGfx()) {
   12308                         pw.print(",high-end-gfx");
   12309                     }
   12310                     pw.println();
   12311                 }
   12312             }
   12313         }
   12314     }
   12315 
   12316     /**
   12317      * Searches array of arguments for the specified string
   12318      * @param args array of argument strings
   12319      * @param value value to search for
   12320      * @return true if the value is contained in the array
   12321      */
   12322     private static boolean scanArgs(String[] args, String value) {
   12323         if (args != null) {
   12324             for (String arg : args) {
   12325                 if (value.equals(arg)) {
   12326                     return true;
   12327                 }
   12328             }
   12329         }
   12330         return false;
   12331     }
   12332 
   12333     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   12334             ContentProviderRecord cpr, boolean always) {
   12335         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   12336 
   12337         if (!inLaunching || always) {
   12338             synchronized (cpr) {
   12339                 cpr.launchingApp = null;
   12340                 cpr.notifyAll();
   12341             }
   12342             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   12343             String names[] = cpr.info.authority.split(";");
   12344             for (int j = 0; j < names.length; j++) {
   12345                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   12346             }
   12347         }
   12348 
   12349         for (int i=0; i<cpr.connections.size(); i++) {
   12350             ContentProviderConnection conn = cpr.connections.get(i);
   12351             if (conn.waiting) {
   12352                 // If this connection is waiting for the provider, then we don't
   12353                 // need to mess with its process unless we are always removing
   12354                 // or for some reason the provider is not currently launching.
   12355                 if (inLaunching && !always) {
   12356                     continue;
   12357                 }
   12358             }
   12359             ProcessRecord capp = conn.client;
   12360             conn.dead = true;
   12361             if (conn.stableCount > 0) {
   12362                 if (!capp.persistent && capp.thread != null
   12363                         && capp.pid != 0
   12364                         && capp.pid != MY_PID) {
   12365                     killUnneededProcessLocked(capp, "depends on provider "
   12366                             + cpr.name.flattenToShortString()
   12367                             + " in dying proc " + (proc != null ? proc.processName : "??"));
   12368                 }
   12369             } else if (capp.thread != null && conn.provider.provider != null) {
   12370                 try {
   12371                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   12372                 } catch (RemoteException e) {
   12373                 }
   12374                 // In the protocol here, we don't expect the client to correctly
   12375                 // clean up this connection, we'll just remove it.
   12376                 cpr.connections.remove(i);
   12377                 conn.client.conProviders.remove(conn);
   12378             }
   12379         }
   12380 
   12381         if (inLaunching && always) {
   12382             mLaunchingProviders.remove(cpr);
   12383         }
   12384         return inLaunching;
   12385     }
   12386 
   12387     /**
   12388      * Main code for cleaning up a process when it has gone away.  This is
   12389      * called both as a result of the process dying, or directly when stopping
   12390      * a process when running in single process mode.
   12391      */
   12392     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   12393             boolean restarting, boolean allowRestart, int index) {
   12394         if (index >= 0) {
   12395             removeLruProcessLocked(app);
   12396         }
   12397 
   12398         mProcessesToGc.remove(app);
   12399         mPendingPssProcesses.remove(app);
   12400 
   12401         // Dismiss any open dialogs.
   12402         if (app.crashDialog != null && !app.forceCrashReport) {
   12403             app.crashDialog.dismiss();
   12404             app.crashDialog = null;
   12405         }
   12406         if (app.anrDialog != null) {
   12407             app.anrDialog.dismiss();
   12408             app.anrDialog = null;
   12409         }
   12410         if (app.waitDialog != null) {
   12411             app.waitDialog.dismiss();
   12412             app.waitDialog = null;
   12413         }
   12414 
   12415         app.crashing = false;
   12416         app.notResponding = false;
   12417 
   12418         app.resetPackageList(mProcessStats);
   12419         app.unlinkDeathRecipient();
   12420         app.makeInactive(mProcessStats);
   12421         app.forcingToForeground = null;
   12422         app.foregroundServices = false;
   12423         app.foregroundActivities = false;
   12424         app.hasShownUi = false;
   12425         app.hasAboveClient = false;
   12426 
   12427         mServices.killServicesLocked(app, allowRestart);
   12428 
   12429         boolean restart = false;
   12430 
   12431         // Remove published content providers.
   12432         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   12433             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   12434             final boolean always = app.bad || !allowRestart;
   12435             if (removeDyingProviderLocked(app, cpr, always) || always) {
   12436                 // We left the provider in the launching list, need to
   12437                 // restart it.
   12438                 restart = true;
   12439             }
   12440 
   12441             cpr.provider = null;
   12442             cpr.proc = null;
   12443         }
   12444         app.pubProviders.clear();
   12445 
   12446         // Take care of any launching providers waiting for this process.
   12447         if (checkAppInLaunchingProvidersLocked(app, false)) {
   12448             restart = true;
   12449         }
   12450 
   12451         // Unregister from connected content providers.
   12452         if (!app.conProviders.isEmpty()) {
   12453             for (int i=0; i<app.conProviders.size(); i++) {
   12454                 ContentProviderConnection conn = app.conProviders.get(i);
   12455                 conn.provider.connections.remove(conn);
   12456             }
   12457             app.conProviders.clear();
   12458         }
   12459 
   12460         // At this point there may be remaining entries in mLaunchingProviders
   12461         // where we were the only one waiting, so they are no longer of use.
   12462         // Look for these and clean up if found.
   12463         // XXX Commented out for now.  Trying to figure out a way to reproduce
   12464         // the actual situation to identify what is actually going on.
   12465         if (false) {
   12466             for (int i=0; i<mLaunchingProviders.size(); i++) {
   12467                 ContentProviderRecord cpr = (ContentProviderRecord)
   12468                         mLaunchingProviders.get(i);
   12469                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   12470                     synchronized (cpr) {
   12471                         cpr.launchingApp = null;
   12472                         cpr.notifyAll();
   12473                     }
   12474                 }
   12475             }
   12476         }
   12477 
   12478         skipCurrentReceiverLocked(app);
   12479 
   12480         // Unregister any receivers.
   12481         for (int i=app.receivers.size()-1; i>=0; i--) {
   12482             removeReceiverLocked(app.receivers.valueAt(i));
   12483         }
   12484         app.receivers.clear();
   12485 
   12486         // If the app is undergoing backup, tell the backup manager about it
   12487         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   12488             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   12489                     + mBackupTarget.appInfo + " died during backup");
   12490             try {
   12491                 IBackupManager bm = IBackupManager.Stub.asInterface(
   12492                         ServiceManager.getService(Context.BACKUP_SERVICE));
   12493                 bm.agentDisconnected(app.info.packageName);
   12494             } catch (RemoteException e) {
   12495                 // can't happen; backup manager is local
   12496             }
   12497         }
   12498 
   12499         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   12500             ProcessChangeItem item = mPendingProcessChanges.get(i);
   12501             if (item.pid == app.pid) {
   12502                 mPendingProcessChanges.remove(i);
   12503                 mAvailProcessChanges.add(item);
   12504             }
   12505         }
   12506         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   12507 
   12508         // If the caller is restarting this app, then leave it in its
   12509         // current lists and let the caller take care of it.
   12510         if (restarting) {
   12511             return;
   12512         }
   12513 
   12514         if (!app.persistent || app.isolated) {
   12515             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   12516                     "Removing non-persistent process during cleanup: " + app);
   12517             mProcessNames.remove(app.processName, app.uid);
   12518             mIsolatedProcesses.remove(app.uid);
   12519             if (mHeavyWeightProcess == app) {
   12520                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   12521                         mHeavyWeightProcess.userId, 0));
   12522                 mHeavyWeightProcess = null;
   12523             }
   12524         } else if (!app.removed) {
   12525             // This app is persistent, so we need to keep its record around.
   12526             // If it is not already on the pending app list, add it there
   12527             // and start a new process for it.
   12528             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   12529                 mPersistentStartingProcesses.add(app);
   12530                 restart = true;
   12531             }
   12532         }
   12533         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   12534                 "Clean-up removing on hold: " + app);
   12535         mProcessesOnHold.remove(app);
   12536 
   12537         if (app == mHomeProcess) {
   12538             mHomeProcess = null;
   12539         }
   12540         if (app == mPreviousProcess) {
   12541             mPreviousProcess = null;
   12542         }
   12543 
   12544         if (restart && !app.isolated) {
   12545             // We have components that still need to be running in the
   12546             // process, so re-launch it.
   12547             mProcessNames.put(app.processName, app.uid, app);
   12548             startProcessLocked(app, "restart", app.processName);
   12549         } else if (app.pid > 0 && app.pid != MY_PID) {
   12550             // Goodbye!
   12551             synchronized (mPidsSelfLocked) {
   12552                 mPidsSelfLocked.remove(app.pid);
   12553                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   12554             }
   12555             app.setPid(0);
   12556         }
   12557     }
   12558 
   12559     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   12560         // Look through the content providers we are waiting to have launched,
   12561         // and if any run in this process then either schedule a restart of
   12562         // the process or kill the client waiting for it if this process has
   12563         // gone bad.
   12564         int NL = mLaunchingProviders.size();
   12565         boolean restart = false;
   12566         for (int i=0; i<NL; i++) {
   12567             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   12568             if (cpr.launchingApp == app) {
   12569                 if (!alwaysBad && !app.bad) {
   12570                     restart = true;
   12571                 } else {
   12572                     removeDyingProviderLocked(app, cpr, true);
   12573                     // cpr should have been removed from mLaunchingProviders
   12574                     NL = mLaunchingProviders.size();
   12575                     i--;
   12576                 }
   12577             }
   12578         }
   12579         return restart;
   12580     }
   12581 
   12582     // =========================================================
   12583     // SERVICES
   12584     // =========================================================
   12585 
   12586     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   12587             int flags) {
   12588         enforceNotIsolatedCaller("getServices");
   12589         synchronized (this) {
   12590             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   12591         }
   12592     }
   12593 
   12594     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   12595         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   12596         synchronized (this) {
   12597             return mServices.getRunningServiceControlPanelLocked(name);
   12598         }
   12599     }
   12600 
   12601     public ComponentName startService(IApplicationThread caller, Intent service,
   12602             String resolvedType, int userId) {
   12603         enforceNotIsolatedCaller("startService");
   12604         // Refuse possible leaked file descriptors
   12605         if (service != null && service.hasFileDescriptors() == true) {
   12606             throw new IllegalArgumentException("File descriptors passed in Intent");
   12607         }
   12608 
   12609         if (DEBUG_SERVICE)
   12610             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   12611         synchronized(this) {
   12612             final int callingPid = Binder.getCallingPid();
   12613             final int callingUid = Binder.getCallingUid();
   12614             final long origId = Binder.clearCallingIdentity();
   12615             ComponentName res = mServices.startServiceLocked(caller, service,
   12616                     resolvedType, callingPid, callingUid, userId);
   12617             Binder.restoreCallingIdentity(origId);
   12618             return res;
   12619         }
   12620     }
   12621 
   12622     ComponentName startServiceInPackage(int uid,
   12623             Intent service, String resolvedType, int userId) {
   12624         synchronized(this) {
   12625             if (DEBUG_SERVICE)
   12626                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   12627             final long origId = Binder.clearCallingIdentity();
   12628             ComponentName res = mServices.startServiceLocked(null, service,
   12629                     resolvedType, -1, uid, userId);
   12630             Binder.restoreCallingIdentity(origId);
   12631             return res;
   12632         }
   12633     }
   12634 
   12635     public int stopService(IApplicationThread caller, Intent service,
   12636             String resolvedType, int userId) {
   12637         enforceNotIsolatedCaller("stopService");
   12638         // Refuse possible leaked file descriptors
   12639         if (service != null && service.hasFileDescriptors() == true) {
   12640             throw new IllegalArgumentException("File descriptors passed in Intent");
   12641         }
   12642 
   12643         synchronized(this) {
   12644             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   12645         }
   12646     }
   12647 
   12648     public IBinder peekService(Intent service, String resolvedType) {
   12649         enforceNotIsolatedCaller("peekService");
   12650         // Refuse possible leaked file descriptors
   12651         if (service != null && service.hasFileDescriptors() == true) {
   12652             throw new IllegalArgumentException("File descriptors passed in Intent");
   12653         }
   12654         synchronized(this) {
   12655             return mServices.peekServiceLocked(service, resolvedType);
   12656         }
   12657     }
   12658 
   12659     public boolean stopServiceToken(ComponentName className, IBinder token,
   12660             int startId) {
   12661         synchronized(this) {
   12662             return mServices.stopServiceTokenLocked(className, token, startId);
   12663         }
   12664     }
   12665 
   12666     public void setServiceForeground(ComponentName className, IBinder token,
   12667             int id, Notification notification, boolean removeNotification) {
   12668         synchronized(this) {
   12669             mServices.setServiceForegroundLocked(className, token, id, notification,
   12670                     removeNotification);
   12671         }
   12672     }
   12673 
   12674     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   12675             boolean requireFull, String name, String callerPackage) {
   12676         final int callingUserId = UserHandle.getUserId(callingUid);
   12677         if (callingUserId != userId) {
   12678             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   12679                 if ((requireFull || checkComponentPermission(
   12680                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12681                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
   12682                         && checkComponentPermission(
   12683                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   12684                                 callingPid, callingUid, -1, true)
   12685                                 != PackageManager.PERMISSION_GRANTED) {
   12686                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   12687                         // In this case, they would like to just execute as their
   12688                         // owner user instead of failing.
   12689                         userId = callingUserId;
   12690                     } else {
   12691                         StringBuilder builder = new StringBuilder(128);
   12692                         builder.append("Permission Denial: ");
   12693                         builder.append(name);
   12694                         if (callerPackage != null) {
   12695                             builder.append(" from ");
   12696                             builder.append(callerPackage);
   12697                         }
   12698                         builder.append(" asks to run as user ");
   12699                         builder.append(userId);
   12700                         builder.append(" but is calling from user ");
   12701                         builder.append(UserHandle.getUserId(callingUid));
   12702                         builder.append("; this requires ");
   12703                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
   12704                         if (!requireFull) {
   12705                             builder.append(" or ");
   12706                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
   12707                         }
   12708                         String msg = builder.toString();
   12709                         Slog.w(TAG, msg);
   12710                         throw new SecurityException(msg);
   12711                     }
   12712                 }
   12713             }
   12714             if (userId == UserHandle.USER_CURRENT
   12715                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   12716                 // Note that we may be accessing this outside of a lock...
   12717                 // shouldn't be a big deal, if this is being called outside
   12718                 // of a locked context there is intrinsically a race with
   12719                 // the value the caller will receive and someone else changing it.
   12720                 userId = mCurrentUserId;
   12721             }
   12722             if (!allowAll && userId < 0) {
   12723                 throw new IllegalArgumentException(
   12724                         "Call does not support special user #" + userId);
   12725             }
   12726         }
   12727         return userId;
   12728     }
   12729 
   12730     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   12731             String className, int flags) {
   12732         boolean result = false;
   12733         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   12734             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
   12735                 if (ActivityManager.checkUidPermission(
   12736                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12737                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   12738                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   12739                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   12740                             + " requests FLAG_SINGLE_USER, but app does not hold "
   12741                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
   12742                     Slog.w(TAG, msg);
   12743                     throw new SecurityException(msg);
   12744                 }
   12745                 result = true;
   12746             }
   12747         } else if (componentProcessName == aInfo.packageName) {
   12748             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   12749         } else if ("system".equals(componentProcessName)) {
   12750             result = true;
   12751         }
   12752         if (DEBUG_MU) {
   12753             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   12754                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   12755         }
   12756         return result;
   12757     }
   12758 
   12759     public int bindService(IApplicationThread caller, IBinder token,
   12760             Intent service, String resolvedType,
   12761             IServiceConnection connection, int flags, int userId) {
   12762         enforceNotIsolatedCaller("bindService");
   12763         // Refuse possible leaked file descriptors
   12764         if (service != null && service.hasFileDescriptors() == true) {
   12765             throw new IllegalArgumentException("File descriptors passed in Intent");
   12766         }
   12767 
   12768         synchronized(this) {
   12769             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   12770                     connection, flags, userId);
   12771         }
   12772     }
   12773 
   12774     public boolean unbindService(IServiceConnection connection) {
   12775         synchronized (this) {
   12776             return mServices.unbindServiceLocked(connection);
   12777         }
   12778     }
   12779 
   12780     public void publishService(IBinder token, Intent intent, IBinder service) {
   12781         // Refuse possible leaked file descriptors
   12782         if (intent != null && intent.hasFileDescriptors() == true) {
   12783             throw new IllegalArgumentException("File descriptors passed in Intent");
   12784         }
   12785 
   12786         synchronized(this) {
   12787             if (!(token instanceof ServiceRecord)) {
   12788                 throw new IllegalArgumentException("Invalid service token");
   12789             }
   12790             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   12791         }
   12792     }
   12793 
   12794     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   12795         // Refuse possible leaked file descriptors
   12796         if (intent != null && intent.hasFileDescriptors() == true) {
   12797             throw new IllegalArgumentException("File descriptors passed in Intent");
   12798         }
   12799 
   12800         synchronized(this) {
   12801             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   12802         }
   12803     }
   12804 
   12805     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   12806         synchronized(this) {
   12807             if (!(token instanceof ServiceRecord)) {
   12808                 throw new IllegalArgumentException("Invalid service token");
   12809             }
   12810             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   12811         }
   12812     }
   12813 
   12814     // =========================================================
   12815     // BACKUP AND RESTORE
   12816     // =========================================================
   12817 
   12818     // Cause the target app to be launched if necessary and its backup agent
   12819     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   12820     // activity manager to announce its creation.
   12821     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   12822         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   12823         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
   12824 
   12825         synchronized(this) {
   12826             // !!! TODO: currently no check here that we're already bound
   12827             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   12828             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12829             synchronized (stats) {
   12830                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   12831             }
   12832 
   12833             // Backup agent is now in use, its package can't be stopped.
   12834             try {
   12835                 AppGlobals.getPackageManager().setPackageStoppedState(
   12836                         app.packageName, false, UserHandle.getUserId(app.uid));
   12837             } catch (RemoteException e) {
   12838             } catch (IllegalArgumentException e) {
   12839                 Slog.w(TAG, "Failed trying to unstop package "
   12840                         + app.packageName + ": " + e);
   12841             }
   12842 
   12843             BackupRecord r = new BackupRecord(ss, app, backupMode);
   12844             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   12845                     ? new ComponentName(app.packageName, app.backupAgentName)
   12846                     : new ComponentName("android", "FullBackupAgent");
   12847             // startProcessLocked() returns existing proc's record if it's already running
   12848             ProcessRecord proc = startProcessLocked(app.processName, app,
   12849                     false, 0, "backup", hostingName, false, false, false);
   12850             if (proc == null) {
   12851                 Slog.e(TAG, "Unable to start backup agent process " + r);
   12852                 return false;
   12853             }
   12854 
   12855             r.app = proc;
   12856             mBackupTarget = r;
   12857             mBackupAppName = app.packageName;
   12858 
   12859             // Try not to kill the process during backup
   12860             updateOomAdjLocked(proc);
   12861 
   12862             // If the process is already attached, schedule the creation of the backup agent now.
   12863             // If it is not yet live, this will be done when it attaches to the framework.
   12864             if (proc.thread != null) {
   12865                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   12866                 try {
   12867                     proc.thread.scheduleCreateBackupAgent(app,
   12868                             compatibilityInfoForPackageLocked(app), backupMode);
   12869                 } catch (RemoteException e) {
   12870                     // Will time out on the backup manager side
   12871                 }
   12872             } else {
   12873                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   12874             }
   12875             // Invariants: at this point, the target app process exists and the application
   12876             // is either already running or in the process of coming up.  mBackupTarget and
   12877             // mBackupAppName describe the app, so that when it binds back to the AM we
   12878             // know that it's scheduled for a backup-agent operation.
   12879         }
   12880 
   12881         return true;
   12882     }
   12883 
   12884     @Override
   12885     public void clearPendingBackup() {
   12886         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   12887         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   12888 
   12889         synchronized (this) {
   12890             mBackupTarget = null;
   12891             mBackupAppName = null;
   12892         }
   12893     }
   12894 
   12895     // A backup agent has just come up
   12896     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   12897         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   12898                 + " = " + agent);
   12899 
   12900         synchronized(this) {
   12901             if (!agentPackageName.equals(mBackupAppName)) {
   12902                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   12903                 return;
   12904             }
   12905         }
   12906 
   12907         long oldIdent = Binder.clearCallingIdentity();
   12908         try {
   12909             IBackupManager bm = IBackupManager.Stub.asInterface(
   12910                     ServiceManager.getService(Context.BACKUP_SERVICE));
   12911             bm.agentConnected(agentPackageName, agent);
   12912         } catch (RemoteException e) {
   12913             // can't happen; the backup manager service is local
   12914         } catch (Exception e) {
   12915             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   12916             e.printStackTrace();
   12917         } finally {
   12918             Binder.restoreCallingIdentity(oldIdent);
   12919         }
   12920     }
   12921 
   12922     // done with this agent
   12923     public void unbindBackupAgent(ApplicationInfo appInfo) {
   12924         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   12925         if (appInfo == null) {
   12926             Slog.w(TAG, "unbind backup agent for null app");
   12927             return;
   12928         }
   12929 
   12930         synchronized(this) {
   12931             try {
   12932                 if (mBackupAppName == null) {
   12933                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   12934                     return;
   12935                 }
   12936 
   12937                 if (!mBackupAppName.equals(appInfo.packageName)) {
   12938                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   12939                     return;
   12940                 }
   12941 
   12942                 // Not backing this app up any more; reset its OOM adjustment
   12943                 final ProcessRecord proc = mBackupTarget.app;
   12944                 updateOomAdjLocked(proc);
   12945 
   12946                 // If the app crashed during backup, 'thread' will be null here
   12947                 if (proc.thread != null) {
   12948                     try {
   12949                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   12950                                 compatibilityInfoForPackageLocked(appInfo));
   12951                     } catch (Exception e) {
   12952                         Slog.e(TAG, "Exception when unbinding backup agent:");
   12953                         e.printStackTrace();
   12954                     }
   12955                 }
   12956             } finally {
   12957                 mBackupTarget = null;
   12958                 mBackupAppName = null;
   12959             }
   12960         }
   12961     }
   12962     // =========================================================
   12963     // BROADCASTS
   12964     // =========================================================
   12965 
   12966     private final List getStickiesLocked(String action, IntentFilter filter,
   12967             List cur, int userId) {
   12968         final ContentResolver resolver = mContext.getContentResolver();
   12969         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12970         if (stickies == null) {
   12971             return cur;
   12972         }
   12973         final ArrayList<Intent> list = stickies.get(action);
   12974         if (list == null) {
   12975             return cur;
   12976         }
   12977         int N = list.size();
   12978         for (int i=0; i<N; i++) {
   12979             Intent intent = list.get(i);
   12980             if (filter.match(resolver, intent, true, TAG) >= 0) {
   12981                 if (cur == null) {
   12982                     cur = new ArrayList<Intent>();
   12983                 }
   12984                 cur.add(intent);
   12985             }
   12986         }
   12987         return cur;
   12988     }
   12989 
   12990     boolean isPendingBroadcastProcessLocked(int pid) {
   12991         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   12992                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   12993     }
   12994 
   12995     void skipPendingBroadcastLocked(int pid) {
   12996             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   12997             for (BroadcastQueue queue : mBroadcastQueues) {
   12998                 queue.skipPendingBroadcastLocked(pid);
   12999             }
   13000     }
   13001 
   13002     // The app just attached; send any pending broadcasts that it should receive
   13003     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   13004         boolean didSomething = false;
   13005         for (BroadcastQueue queue : mBroadcastQueues) {
   13006             didSomething |= queue.sendPendingBroadcastsLocked(app);
   13007         }
   13008         return didSomething;
   13009     }
   13010 
   13011     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   13012             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   13013         enforceNotIsolatedCaller("registerReceiver");
   13014         int callingUid;
   13015         int callingPid;
   13016         synchronized(this) {
   13017             ProcessRecord callerApp = null;
   13018             if (caller != null) {
   13019                 callerApp = getRecordForAppLocked(caller);
   13020                 if (callerApp == null) {
   13021                     throw new SecurityException(
   13022                             "Unable to find app for caller " + caller
   13023                             + " (pid=" + Binder.getCallingPid()
   13024                             + ") when registering receiver " + receiver);
   13025                 }
   13026                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   13027                         !callerApp.pkgList.containsKey(callerPackage) &&
   13028                         !"android".equals(callerPackage)) {
   13029                     throw new SecurityException("Given caller package " + callerPackage
   13030                             + " is not running in process " + callerApp);
   13031                 }
   13032                 callingUid = callerApp.info.uid;
   13033                 callingPid = callerApp.pid;
   13034             } else {
   13035                 callerPackage = null;
   13036                 callingUid = Binder.getCallingUid();
   13037                 callingPid = Binder.getCallingPid();
   13038             }
   13039 
   13040             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   13041                     true, true, "registerReceiver", callerPackage);
   13042 
   13043             List allSticky = null;
   13044 
   13045             // Look for any matching sticky broadcasts...
   13046             Iterator actions = filter.actionsIterator();
   13047             if (actions != null) {
   13048                 while (actions.hasNext()) {
   13049                     String action = (String)actions.next();
   13050                     allSticky = getStickiesLocked(action, filter, allSticky,
   13051                             UserHandle.USER_ALL);
   13052                     allSticky = getStickiesLocked(action, filter, allSticky,
   13053                             UserHandle.getUserId(callingUid));
   13054                 }
   13055             } else {
   13056                 allSticky = getStickiesLocked(null, filter, allSticky,
   13057                         UserHandle.USER_ALL);
   13058                 allSticky = getStickiesLocked(null, filter, allSticky,
   13059                         UserHandle.getUserId(callingUid));
   13060             }
   13061 
   13062             // The first sticky in the list is returned directly back to
   13063             // the client.
   13064             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   13065 
   13066             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   13067                     + ": " + sticky);
   13068 
   13069             if (receiver == null) {
   13070                 return sticky;
   13071             }
   13072 
   13073             ReceiverList rl
   13074                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   13075             if (rl == null) {
   13076                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   13077                         userId, receiver);
   13078                 if (rl.app != null) {
   13079                     rl.app.receivers.add(rl);
   13080                 } else {
   13081                     try {
   13082                         receiver.asBinder().linkToDeath(rl, 0);
   13083                     } catch (RemoteException e) {
   13084                         return sticky;
   13085                     }
   13086                     rl.linkedToDeath = true;
   13087                 }
   13088                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   13089             } else if (rl.uid != callingUid) {
   13090                 throw new IllegalArgumentException(
   13091                         "Receiver requested to register for uid " + callingUid
   13092                         + " was previously registered for uid " + rl.uid);
   13093             } else if (rl.pid != callingPid) {
   13094                 throw new IllegalArgumentException(
   13095                         "Receiver requested to register for pid " + callingPid
   13096                         + " was previously registered for pid " + rl.pid);
   13097             } else if (rl.userId != userId) {
   13098                 throw new IllegalArgumentException(
   13099                         "Receiver requested to register for user " + userId
   13100                         + " was previously registered for user " + rl.userId);
   13101             }
   13102             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   13103                     permission, callingUid, userId);
   13104             rl.add(bf);
   13105             if (!bf.debugCheck()) {
   13106                 Slog.w(TAG, "==> For Dynamic broadast");
   13107             }
   13108             mReceiverResolver.addFilter(bf);
   13109 
   13110             // Enqueue broadcasts for all existing stickies that match
   13111             // this filter.
   13112             if (allSticky != null) {
   13113                 ArrayList receivers = new ArrayList();
   13114                 receivers.add(bf);
   13115 
   13116                 int N = allSticky.size();
   13117                 for (int i=0; i<N; i++) {
   13118                     Intent intent = (Intent)allSticky.get(i);
   13119                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   13120                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   13121                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   13122                             null, null, false, true, true, -1);
   13123                     queue.enqueueParallelBroadcastLocked(r);
   13124                     queue.scheduleBroadcastsLocked();
   13125                 }
   13126             }
   13127 
   13128             return sticky;
   13129         }
   13130     }
   13131 
   13132     public void unregisterReceiver(IIntentReceiver receiver) {
   13133         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   13134 
   13135         final long origId = Binder.clearCallingIdentity();
   13136         try {
   13137             boolean doTrim = false;
   13138 
   13139             synchronized(this) {
   13140                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   13141                 if (rl != null) {
   13142                     if (rl.curBroadcast != null) {
   13143                         BroadcastRecord r = rl.curBroadcast;
   13144                         final boolean doNext = finishReceiverLocked(
   13145                                 receiver.asBinder(), r.resultCode, r.resultData,
   13146                                 r.resultExtras, r.resultAbort);
   13147                         if (doNext) {
   13148                             doTrim = true;
   13149                             r.queue.processNextBroadcast(false);
   13150                         }
   13151                     }
   13152 
   13153                     if (rl.app != null) {
   13154                         rl.app.receivers.remove(rl);
   13155                     }
   13156                     removeReceiverLocked(rl);
   13157                     if (rl.linkedToDeath) {
   13158                         rl.linkedToDeath = false;
   13159                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   13160                     }
   13161                 }
   13162             }
   13163 
   13164             // If we actually concluded any broadcasts, we might now be able
   13165             // to trim the recipients' apps from our working set
   13166             if (doTrim) {
   13167                 trimApplications();
   13168                 return;
   13169             }
   13170 
   13171         } finally {
   13172             Binder.restoreCallingIdentity(origId);
   13173         }
   13174     }
   13175 
   13176     void removeReceiverLocked(ReceiverList rl) {
   13177         mRegisteredReceivers.remove(rl.receiver.asBinder());
   13178         int N = rl.size();
   13179         for (int i=0; i<N; i++) {
   13180             mReceiverResolver.removeFilter(rl.get(i));
   13181         }
   13182     }
   13183 
   13184     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   13185         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13186             ProcessRecord r = mLruProcesses.get(i);
   13187             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   13188                 try {
   13189                     r.thread.dispatchPackageBroadcast(cmd, packages);
   13190                 } catch (RemoteException ex) {
   13191                 }
   13192             }
   13193         }
   13194     }
   13195 
   13196     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   13197             int[] users) {
   13198         List<ResolveInfo> receivers = null;
   13199         try {
   13200             HashSet<ComponentName> singleUserReceivers = null;
   13201             boolean scannedFirstReceivers = false;
   13202             for (int user : users) {
   13203                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   13204                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   13205                 if (user != 0 && newReceivers != null) {
   13206                     // If this is not the primary user, we need to check for
   13207                     // any receivers that should be filtered out.
   13208                     for (int i=0; i<newReceivers.size(); i++) {
   13209                         ResolveInfo ri = newReceivers.get(i);
   13210                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   13211                             newReceivers.remove(i);
   13212                             i--;
   13213                         }
   13214                     }
   13215                 }
   13216                 if (newReceivers != null && newReceivers.size() == 0) {
   13217                     newReceivers = null;
   13218                 }
   13219                 if (receivers == null) {
   13220                     receivers = newReceivers;
   13221                 } else if (newReceivers != null) {
   13222                     // We need to concatenate the additional receivers
   13223                     // found with what we have do far.  This would be easy,
   13224                     // but we also need to de-dup any receivers that are
   13225                     // singleUser.
   13226                     if (!scannedFirstReceivers) {
   13227                         // Collect any single user receivers we had already retrieved.
   13228                         scannedFirstReceivers = true;
   13229                         for (int i=0; i<receivers.size(); i++) {
   13230                             ResolveInfo ri = receivers.get(i);
   13231                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   13232                                 ComponentName cn = new ComponentName(
   13233                                         ri.activityInfo.packageName, ri.activityInfo.name);
   13234                                 if (singleUserReceivers == null) {
   13235                                     singleUserReceivers = new HashSet<ComponentName>();
   13236                                 }
   13237                                 singleUserReceivers.add(cn);
   13238                             }
   13239                         }
   13240                     }
   13241                     // Add the new results to the existing results, tracking
   13242                     // and de-dupping single user receivers.
   13243                     for (int i=0; i<newReceivers.size(); i++) {
   13244                         ResolveInfo ri = newReceivers.get(i);
   13245                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   13246                             ComponentName cn = new ComponentName(
   13247                                     ri.activityInfo.packageName, ri.activityInfo.name);
   13248                             if (singleUserReceivers == null) {
   13249                                 singleUserReceivers = new HashSet<ComponentName>();
   13250                             }
   13251                             if (!singleUserReceivers.contains(cn)) {
   13252                                 singleUserReceivers.add(cn);
   13253                                 receivers.add(ri);
   13254                             }
   13255                         } else {
   13256                             receivers.add(ri);
   13257                         }
   13258                     }
   13259                 }
   13260             }
   13261         } catch (RemoteException ex) {
   13262             // pm is in same process, this will never happen.
   13263         }
   13264         return receivers;
   13265     }
   13266 
   13267     private final int broadcastIntentLocked(ProcessRecord callerApp,
   13268             String callerPackage, Intent intent, String resolvedType,
   13269             IIntentReceiver resultTo, int resultCode, String resultData,
   13270             Bundle map, String requiredPermission, int appOp,
   13271             boolean ordered, boolean sticky, int callingPid, int callingUid,
   13272             int userId) {
   13273         intent = new Intent(intent);
   13274 
   13275         // By default broadcasts do not go to stopped apps.
   13276         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   13277 
   13278         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   13279             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   13280             + " ordered=" + ordered + " userid=" + userId);
   13281         if ((resultTo != null) && !ordered) {
   13282             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   13283         }
   13284 
   13285         userId = handleIncomingUser(callingPid, callingUid, userId,
   13286                 true, false, "broadcast", callerPackage);
   13287 
   13288         // Make sure that the user who is receiving this broadcast is started.
   13289         // If not, we will just skip it.
   13290         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   13291             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   13292                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   13293                 Slog.w(TAG, "Skipping broadcast of " + intent
   13294                         + ": user " + userId + " is stopped");
   13295                 return ActivityManager.BROADCAST_SUCCESS;
   13296             }
   13297         }
   13298 
   13299         /*
   13300          * Prevent non-system code (defined here to be non-persistent
   13301          * processes) from sending protected broadcasts.
   13302          */
   13303         int callingAppId = UserHandle.getAppId(callingUid);
   13304         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   13305             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
   13306             callingUid == 0) {
   13307             // Always okay.
   13308         } else if (callerApp == null || !callerApp.persistent) {
   13309             try {
   13310                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   13311                         intent.getAction())) {
   13312                     String msg = "Permission Denial: not allowed to send broadcast "
   13313                             + intent.getAction() + " from pid="
   13314                             + callingPid + ", uid=" + callingUid;
   13315                     Slog.w(TAG, msg);
   13316                     throw new SecurityException(msg);
   13317                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   13318                     // Special case for compatibility: we don't want apps to send this,
   13319                     // but historically it has not been protected and apps may be using it
   13320                     // to poke their own app widget.  So, instead of making it protected,
   13321                     // just limit it to the caller.
   13322                     if (callerApp == null) {
   13323                         String msg = "Permission Denial: not allowed to send broadcast "
   13324                                 + intent.getAction() + " from unknown caller.";
   13325                         Slog.w(TAG, msg);
   13326                         throw new SecurityException(msg);
   13327                     } else if (intent.getComponent() != null) {
   13328                         // They are good enough to send to an explicit component...  verify
   13329                         // it is being sent to the calling app.
   13330                         if (!intent.getComponent().getPackageName().equals(
   13331                                 callerApp.info.packageName)) {
   13332                             String msg = "Permission Denial: not allowed to send broadcast "
   13333                                     + intent.getAction() + " to "
   13334                                     + intent.getComponent().getPackageName() + " from "
   13335                                     + callerApp.info.packageName;
   13336                             Slog.w(TAG, msg);
   13337                             throw new SecurityException(msg);
   13338                         }
   13339                     } else {
   13340                         // Limit broadcast to their own package.
   13341                         intent.setPackage(callerApp.info.packageName);
   13342                     }
   13343                 }
   13344             } catch (RemoteException e) {
   13345                 Slog.w(TAG, "Remote exception", e);
   13346                 return ActivityManager.BROADCAST_SUCCESS;
   13347             }
   13348         }
   13349 
   13350         // Handle special intents: if this broadcast is from the package
   13351         // manager about a package being removed, we need to remove all of
   13352         // its activities from the history stack.
   13353         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   13354                 intent.getAction());
   13355         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   13356                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   13357                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   13358                 || uidRemoved) {
   13359             if (checkComponentPermission(
   13360                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   13361                     callingPid, callingUid, -1, true)
   13362                     == PackageManager.PERMISSION_GRANTED) {
   13363                 if (uidRemoved) {
   13364                     final Bundle intentExtras = intent.getExtras();
   13365                     final int uid = intentExtras != null
   13366                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   13367                     if (uid >= 0) {
   13368                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   13369                         synchronized (bs) {
   13370                             bs.removeUidStatsLocked(uid);
   13371                         }
   13372                         mAppOpsService.uidRemoved(uid);
   13373                     }
   13374                 } else {
   13375                     // If resources are unavailable just force stop all
   13376                     // those packages and flush the attribute cache as well.
   13377                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   13378                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13379                         if (list != null && (list.length > 0)) {
   13380                             for (String pkg : list) {
   13381                                 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
   13382                                         "storage unmount");
   13383                             }
   13384                             sendPackageBroadcastLocked(
   13385                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   13386                         }
   13387                     } else {
   13388                         Uri data = intent.getData();
   13389                         String ssp;
   13390                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13391                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
   13392                                     intent.getAction());
   13393                             boolean fullUninstall = removed &&
   13394                                     !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
   13395                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   13396                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
   13397                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
   13398                                         false, fullUninstall, userId,
   13399                                         removed ? "pkg removed" : "pkg changed");
   13400                             }
   13401                             if (removed) {
   13402                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   13403                                         new String[] {ssp}, userId);
   13404                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
   13405                                     mAppOpsService.packageRemoved(
   13406                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   13407 
   13408                                     // Remove all permissions granted from/to this package
   13409                                     removeUriPermissionsForPackageLocked(ssp, userId, true);
   13410                                 }
   13411                             }
   13412                         }
   13413                     }
   13414                 }
   13415             } else {
   13416                 String msg = "Permission Denial: " + intent.getAction()
   13417                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   13418                         + ", uid=" + callingUid + ")"
   13419                         + " requires "
   13420                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   13421                 Slog.w(TAG, msg);
   13422                 throw new SecurityException(msg);
   13423             }
   13424 
   13425         // Special case for adding a package: by default turn on compatibility
   13426         // mode.
   13427         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   13428             Uri data = intent.getData();
   13429             String ssp;
   13430             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13431                 mCompatModePackages.handlePackageAddedLocked(ssp,
   13432                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   13433             }
   13434         }
   13435 
   13436         /*
   13437          * If this is the time zone changed action, queue up a message that will reset the timezone
   13438          * of all currently running processes. This message will get queued up before the broadcast
   13439          * happens.
   13440          */
   13441         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   13442             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   13443         }
   13444 
   13445         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   13446             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   13447         }
   13448 
   13449         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   13450             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   13451             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   13452         }
   13453 
   13454         // Add to the sticky list if requested.
   13455         if (sticky) {
   13456             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   13457                     callingPid, callingUid)
   13458                     != PackageManager.PERMISSION_GRANTED) {
   13459                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   13460                         + callingPid + ", uid=" + callingUid
   13461                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13462                 Slog.w(TAG, msg);
   13463                 throw new SecurityException(msg);
   13464             }
   13465             if (requiredPermission != null) {
   13466                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   13467                         + " and enforce permission " + requiredPermission);
   13468                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   13469             }
   13470             if (intent.getComponent() != null) {
   13471                 throw new SecurityException(
   13472                         "Sticky broadcasts can't target a specific component");
   13473             }
   13474             // We use userId directly here, since the "all" target is maintained
   13475             // as a separate set of sticky broadcasts.
   13476             if (userId != UserHandle.USER_ALL) {
   13477                 // But first, if this is not a broadcast to all users, then
   13478                 // make sure it doesn't conflict with an existing broadcast to
   13479                 // all users.
   13480                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   13481                         UserHandle.USER_ALL);
   13482                 if (stickies != null) {
   13483                     ArrayList<Intent> list = stickies.get(intent.getAction());
   13484                     if (list != null) {
   13485                         int N = list.size();
   13486                         int i;
   13487                         for (i=0; i<N; i++) {
   13488                             if (intent.filterEquals(list.get(i))) {
   13489                                 throw new IllegalArgumentException(
   13490                                         "Sticky broadcast " + intent + " for user "
   13491                                         + userId + " conflicts with existing global broadcast");
   13492                             }
   13493                         }
   13494                     }
   13495                 }
   13496             }
   13497             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13498             if (stickies == null) {
   13499                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   13500                 mStickyBroadcasts.put(userId, stickies);
   13501             }
   13502             ArrayList<Intent> list = stickies.get(intent.getAction());
   13503             if (list == null) {
   13504                 list = new ArrayList<Intent>();
   13505                 stickies.put(intent.getAction(), list);
   13506             }
   13507             int N = list.size();
   13508             int i;
   13509             for (i=0; i<N; i++) {
   13510                 if (intent.filterEquals(list.get(i))) {
   13511                     // This sticky already exists, replace it.
   13512                     list.set(i, new Intent(intent));
   13513                     break;
   13514                 }
   13515             }
   13516             if (i >= N) {
   13517                 list.add(new Intent(intent));
   13518             }
   13519         }
   13520 
   13521         int[] users;
   13522         if (userId == UserHandle.USER_ALL) {
   13523             // Caller wants broadcast to go to all started users.
   13524             users = mStartedUserArray;
   13525         } else {
   13526             // Caller wants broadcast to go to one specific user.
   13527             users = new int[] {userId};
   13528         }
   13529 
   13530         // Figure out who all will receive this broadcast.
   13531         List receivers = null;
   13532         List<BroadcastFilter> registeredReceivers = null;
   13533         // Need to resolve the intent to interested receivers...
   13534         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   13535                  == 0) {
   13536             receivers = collectReceiverComponents(intent, resolvedType, users);
   13537         }
   13538         if (intent.getComponent() == null) {
   13539             registeredReceivers = mReceiverResolver.queryIntent(intent,
   13540                     resolvedType, false, userId);
   13541         }
   13542 
   13543         final boolean replacePending =
   13544                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   13545 
   13546         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   13547                 + " replacePending=" + replacePending);
   13548 
   13549         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   13550         if (!ordered && NR > 0) {
   13551             // If we are not serializing this broadcast, then send the
   13552             // registered receivers separately so they don't wait for the
   13553             // components to be launched.
   13554             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   13555             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13556                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   13557                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   13558                     ordered, sticky, false, userId);
   13559             if (DEBUG_BROADCAST) Slog.v(
   13560                     TAG, "Enqueueing parallel broadcast " + r);
   13561             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   13562             if (!replaced) {
   13563                 queue.enqueueParallelBroadcastLocked(r);
   13564                 queue.scheduleBroadcastsLocked();
   13565             }
   13566             registeredReceivers = null;
   13567             NR = 0;
   13568         }
   13569 
   13570         // Merge into one list.
   13571         int ir = 0;
   13572         if (receivers != null) {
   13573             // A special case for PACKAGE_ADDED: do not allow the package
   13574             // being added to see this broadcast.  This prevents them from
   13575             // using this as a back door to get run as soon as they are
   13576             // installed.  Maybe in the future we want to have a special install
   13577             // broadcast or such for apps, but we'd like to deliberately make
   13578             // this decision.
   13579             String skipPackages[] = null;
   13580             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   13581                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   13582                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   13583                 Uri data = intent.getData();
   13584                 if (data != null) {
   13585                     String pkgName = data.getSchemeSpecificPart();
   13586                     if (pkgName != null) {
   13587                         skipPackages = new String[] { pkgName };
   13588                     }
   13589                 }
   13590             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   13591                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13592             }
   13593             if (skipPackages != null && (skipPackages.length > 0)) {
   13594                 for (String skipPackage : skipPackages) {
   13595                     if (skipPackage != null) {
   13596                         int NT = receivers.size();
   13597                         for (int it=0; it<NT; it++) {
   13598                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   13599                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   13600                                 receivers.remove(it);
   13601                                 it--;
   13602                                 NT--;
   13603                             }
   13604                         }
   13605                     }
   13606                 }
   13607             }
   13608 
   13609             int NT = receivers != null ? receivers.size() : 0;
   13610             int it = 0;
   13611             ResolveInfo curt = null;
   13612             BroadcastFilter curr = null;
   13613             while (it < NT && ir < NR) {
   13614                 if (curt == null) {
   13615                     curt = (ResolveInfo)receivers.get(it);
   13616                 }
   13617                 if (curr == null) {
   13618                     curr = registeredReceivers.get(ir);
   13619                 }
   13620                 if (curr.getPriority() >= curt.priority) {
   13621                     // Insert this broadcast record into the final list.
   13622                     receivers.add(it, curr);
   13623                     ir++;
   13624                     curr = null;
   13625                     it++;
   13626                     NT++;
   13627                 } else {
   13628                     // Skip to the next ResolveInfo in the final list.
   13629                     it++;
   13630                     curt = null;
   13631                 }
   13632             }
   13633         }
   13634         while (ir < NR) {
   13635             if (receivers == null) {
   13636                 receivers = new ArrayList();
   13637             }
   13638             receivers.add(registeredReceivers.get(ir));
   13639             ir++;
   13640         }
   13641 
   13642         if ((receivers != null && receivers.size() > 0)
   13643                 || resultTo != null) {
   13644             BroadcastQueue queue = broadcastQueueForIntent(intent);
   13645             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13646                     callerPackage, callingPid, callingUid, resolvedType,
   13647                     requiredPermission, appOp, receivers, resultTo, resultCode,
   13648                     resultData, map, ordered, sticky, false, userId);
   13649             if (DEBUG_BROADCAST) Slog.v(
   13650                     TAG, "Enqueueing ordered broadcast " + r
   13651                     + ": prev had " + queue.mOrderedBroadcasts.size());
   13652             if (DEBUG_BROADCAST) {
   13653                 int seq = r.intent.getIntExtra("seq", -1);
   13654                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   13655             }
   13656             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   13657             if (!replaced) {
   13658                 queue.enqueueOrderedBroadcastLocked(r);
   13659                 queue.scheduleBroadcastsLocked();
   13660             }
   13661         }
   13662 
   13663         return ActivityManager.BROADCAST_SUCCESS;
   13664     }
   13665 
   13666     final Intent verifyBroadcastLocked(Intent intent) {
   13667         // Refuse possible leaked file descriptors
   13668         if (intent != null && intent.hasFileDescriptors() == true) {
   13669             throw new IllegalArgumentException("File descriptors passed in Intent");
   13670         }
   13671 
   13672         int flags = intent.getFlags();
   13673 
   13674         if (!mProcessesReady) {
   13675             // if the caller really truly claims to know what they're doing, go
   13676             // ahead and allow the broadcast without launching any receivers
   13677             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   13678                 intent = new Intent(intent);
   13679                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13680             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   13681                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   13682                         + " before boot completion");
   13683                 throw new IllegalStateException("Cannot broadcast before boot completed");
   13684             }
   13685         }
   13686 
   13687         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   13688             throw new IllegalArgumentException(
   13689                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   13690         }
   13691 
   13692         return intent;
   13693     }
   13694 
   13695     public final int broadcastIntent(IApplicationThread caller,
   13696             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13697             int resultCode, String resultData, Bundle map,
   13698             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   13699         enforceNotIsolatedCaller("broadcastIntent");
   13700         synchronized(this) {
   13701             intent = verifyBroadcastLocked(intent);
   13702 
   13703             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   13704             final int callingPid = Binder.getCallingPid();
   13705             final int callingUid = Binder.getCallingUid();
   13706             final long origId = Binder.clearCallingIdentity();
   13707             int res = broadcastIntentLocked(callerApp,
   13708                     callerApp != null ? callerApp.info.packageName : null,
   13709                     intent, resolvedType, resultTo,
   13710                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   13711                     callingPid, callingUid, userId);
   13712             Binder.restoreCallingIdentity(origId);
   13713             return res;
   13714         }
   13715     }
   13716 
   13717     int broadcastIntentInPackage(String packageName, int uid,
   13718             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13719             int resultCode, String resultData, Bundle map,
   13720             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   13721         synchronized(this) {
   13722             intent = verifyBroadcastLocked(intent);
   13723 
   13724             final long origId = Binder.clearCallingIdentity();
   13725             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   13726                     resultTo, resultCode, resultData, map, requiredPermission,
   13727                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   13728             Binder.restoreCallingIdentity(origId);
   13729             return res;
   13730         }
   13731     }
   13732 
   13733     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   13734         // Refuse possible leaked file descriptors
   13735         if (intent != null && intent.hasFileDescriptors() == true) {
   13736             throw new IllegalArgumentException("File descriptors passed in Intent");
   13737         }
   13738 
   13739         userId = handleIncomingUser(Binder.getCallingPid(),
   13740                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
   13741 
   13742         synchronized(this) {
   13743             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   13744                     != PackageManager.PERMISSION_GRANTED) {
   13745                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   13746                         + Binder.getCallingPid()
   13747                         + ", uid=" + Binder.getCallingUid()
   13748                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13749                 Slog.w(TAG, msg);
   13750                 throw new SecurityException(msg);
   13751             }
   13752             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13753             if (stickies != null) {
   13754                 ArrayList<Intent> list = stickies.get(intent.getAction());
   13755                 if (list != null) {
   13756                     int N = list.size();
   13757                     int i;
   13758                     for (i=0; i<N; i++) {
   13759                         if (intent.filterEquals(list.get(i))) {
   13760                             list.remove(i);
   13761                             break;
   13762                         }
   13763                     }
   13764                     if (list.size() <= 0) {
   13765                         stickies.remove(intent.getAction());
   13766                     }
   13767                 }
   13768                 if (stickies.size() <= 0) {
   13769                     mStickyBroadcasts.remove(userId);
   13770                 }
   13771             }
   13772         }
   13773     }
   13774 
   13775     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   13776             String resultData, Bundle resultExtras, boolean resultAbort) {
   13777         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   13778         if (r == null) {
   13779             Slog.w(TAG, "finishReceiver called but not found on queue");
   13780             return false;
   13781         }
   13782 
   13783         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   13784     }
   13785 
   13786     void backgroundServicesFinishedLocked(int userId) {
   13787         for (BroadcastQueue queue : mBroadcastQueues) {
   13788             queue.backgroundServicesFinishedLocked(userId);
   13789         }
   13790     }
   13791 
   13792     public void finishReceiver(IBinder who, int resultCode, String resultData,
   13793             Bundle resultExtras, boolean resultAbort) {
   13794         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   13795 
   13796         // Refuse possible leaked file descriptors
   13797         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   13798             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13799         }
   13800 
   13801         final long origId = Binder.clearCallingIdentity();
   13802         try {
   13803             boolean doNext = false;
   13804             BroadcastRecord r;
   13805 
   13806             synchronized(this) {
   13807                 r = broadcastRecordForReceiverLocked(who);
   13808                 if (r != null) {
   13809                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   13810                         resultData, resultExtras, resultAbort, true);
   13811                 }
   13812             }
   13813 
   13814             if (doNext) {
   13815                 r.queue.processNextBroadcast(false);
   13816             }
   13817             trimApplications();
   13818         } finally {
   13819             Binder.restoreCallingIdentity(origId);
   13820         }
   13821     }
   13822 
   13823     // =========================================================
   13824     // INSTRUMENTATION
   13825     // =========================================================
   13826 
   13827     public boolean startInstrumentation(ComponentName className,
   13828             String profileFile, int flags, Bundle arguments,
   13829             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   13830             int userId) {
   13831         enforceNotIsolatedCaller("startInstrumentation");
   13832         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   13833                 userId, false, true, "startInstrumentation", null);
   13834         // Refuse possible leaked file descriptors
   13835         if (arguments != null && arguments.hasFileDescriptors()) {
   13836             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13837         }
   13838 
   13839         synchronized(this) {
   13840             InstrumentationInfo ii = null;
   13841             ApplicationInfo ai = null;
   13842             try {
   13843                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13844                     className, STOCK_PM_FLAGS);
   13845                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   13846                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   13847             } catch (PackageManager.NameNotFoundException e) {
   13848             } catch (RemoteException e) {
   13849             }
   13850             if (ii == null) {
   13851                 reportStartInstrumentationFailure(watcher, className,
   13852                         "Unable to find instrumentation info for: " + className);
   13853                 return false;
   13854             }
   13855             if (ai == null) {
   13856                 reportStartInstrumentationFailure(watcher, className,
   13857                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13858                 return false;
   13859             }
   13860 
   13861             int match = mContext.getPackageManager().checkSignatures(
   13862                     ii.targetPackage, ii.packageName);
   13863             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13864                 String msg = "Permission Denial: starting instrumentation "
   13865                         + className + " from pid="
   13866                         + Binder.getCallingPid()
   13867                         + ", uid=" + Binder.getCallingPid()
   13868                         + " not allowed because package " + ii.packageName
   13869                         + " does not have a signature matching the target "
   13870                         + ii.targetPackage;
   13871                 reportStartInstrumentationFailure(watcher, className, msg);
   13872                 throw new SecurityException(msg);
   13873             }
   13874 
   13875             final long origId = Binder.clearCallingIdentity();
   13876             // Instrumentation can kill and relaunch even persistent processes
   13877             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
   13878                     "start instr");
   13879             ProcessRecord app = addAppLocked(ai, false);
   13880             app.instrumentationClass = className;
   13881             app.instrumentationInfo = ai;
   13882             app.instrumentationProfileFile = profileFile;
   13883             app.instrumentationArguments = arguments;
   13884             app.instrumentationWatcher = watcher;
   13885             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   13886             app.instrumentationResultClass = className;
   13887             Binder.restoreCallingIdentity(origId);
   13888         }
   13889 
   13890         return true;
   13891     }
   13892 
   13893     /**
   13894      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13895      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13896      * the "am" command to report errors with more information.
   13897      *
   13898      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13899      * @param cn The component name of the instrumentation.
   13900      * @param report The error report.
   13901      */
   13902     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13903             ComponentName cn, String report) {
   13904         Slog.w(TAG, report);
   13905         try {
   13906             if (watcher != null) {
   13907                 Bundle results = new Bundle();
   13908                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13909                 results.putString("Error", report);
   13910                 watcher.instrumentationStatus(cn, -1, results);
   13911             }
   13912         } catch (RemoteException e) {
   13913             Slog.w(TAG, e);
   13914         }
   13915     }
   13916 
   13917     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13918         if (app.instrumentationWatcher != null) {
   13919             try {
   13920                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13921                 app.instrumentationWatcher.instrumentationFinished(
   13922                     app.instrumentationClass,
   13923                     resultCode,
   13924                     results);
   13925             } catch (RemoteException e) {
   13926             }
   13927         }
   13928         if (app.instrumentationUiAutomationConnection != null) {
   13929             try {
   13930                 app.instrumentationUiAutomationConnection.shutdown();
   13931             } catch (RemoteException re) {
   13932                 /* ignore */
   13933             }
   13934             // Only a UiAutomation can set this flag and now that
   13935             // it is finished we make sure it is reset to its default.
   13936             mUserIsMonkey = false;
   13937         }
   13938         app.instrumentationWatcher = null;
   13939         app.instrumentationUiAutomationConnection = null;
   13940         app.instrumentationClass = null;
   13941         app.instrumentationInfo = null;
   13942         app.instrumentationProfileFile = null;
   13943         app.instrumentationArguments = null;
   13944 
   13945         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
   13946                 "finished inst");
   13947     }
   13948 
   13949     public void finishInstrumentation(IApplicationThread target,
   13950             int resultCode, Bundle results) {
   13951         int userId = UserHandle.getCallingUserId();
   13952         // Refuse possible leaked file descriptors
   13953         if (results != null && results.hasFileDescriptors()) {
   13954             throw new IllegalArgumentException("File descriptors passed in Intent");
   13955         }
   13956 
   13957         synchronized(this) {
   13958             ProcessRecord app = getRecordForAppLocked(target);
   13959             if (app == null) {
   13960                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13961                 return;
   13962             }
   13963             final long origId = Binder.clearCallingIdentity();
   13964             finishInstrumentationLocked(app, resultCode, results);
   13965             Binder.restoreCallingIdentity(origId);
   13966         }
   13967     }
   13968 
   13969     // =========================================================
   13970     // CONFIGURATION
   13971     // =========================================================
   13972 
   13973     public ConfigurationInfo getDeviceConfigurationInfo() {
   13974         ConfigurationInfo config = new ConfigurationInfo();
   13975         synchronized (this) {
   13976             config.reqTouchScreen = mConfiguration.touchscreen;
   13977             config.reqKeyboardType = mConfiguration.keyboard;
   13978             config.reqNavigation = mConfiguration.navigation;
   13979             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13980                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13981                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13982             }
   13983             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13984                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13985                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13986             }
   13987             config.reqGlEsVersion = GL_ES_VERSION;
   13988         }
   13989         return config;
   13990     }
   13991 
   13992     ActivityStack getFocusedStack() {
   13993         return mStackSupervisor.getFocusedStack();
   13994     }
   13995 
   13996     public Configuration getConfiguration() {
   13997         Configuration ci;
   13998         synchronized(this) {
   13999             ci = new Configuration(mConfiguration);
   14000         }
   14001         return ci;
   14002     }
   14003 
   14004     public void updatePersistentConfiguration(Configuration values) {
   14005         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   14006                 "updateConfiguration()");
   14007         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   14008                 "updateConfiguration()");
   14009         if (values == null) {
   14010             throw new NullPointerException("Configuration must not be null");
   14011         }
   14012 
   14013         synchronized(this) {
   14014             final long origId = Binder.clearCallingIdentity();
   14015             updateConfigurationLocked(values, null, true, false);
   14016             Binder.restoreCallingIdentity(origId);
   14017         }
   14018     }
   14019 
   14020     public void updateConfiguration(Configuration values) {
   14021         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   14022                 "updateConfiguration()");
   14023 
   14024         synchronized(this) {
   14025             if (values == null && mWindowManager != null) {
   14026                 // sentinel: fetch the current configuration from the window manager
   14027                 values = mWindowManager.computeNewConfiguration();
   14028             }
   14029 
   14030             if (mWindowManager != null) {
   14031                 mProcessList.applyDisplaySize(mWindowManager);
   14032             }
   14033 
   14034             final long origId = Binder.clearCallingIdentity();
   14035             if (values != null) {
   14036                 Settings.System.clearConfiguration(values);
   14037             }
   14038             updateConfigurationLocked(values, null, false, false);
   14039             Binder.restoreCallingIdentity(origId);
   14040         }
   14041     }
   14042 
   14043     /**
   14044      * Do either or both things: (1) change the current configuration, and (2)
   14045      * make sure the given activity is running with the (now) current
   14046      * configuration.  Returns true if the activity has been left running, or
   14047      * false if <var>starting</var> is being destroyed to match the new
   14048      * configuration.
   14049      * @param persistent TODO
   14050      */
   14051     boolean updateConfigurationLocked(Configuration values,
   14052             ActivityRecord starting, boolean persistent, boolean initLocale) {
   14053         // do nothing if we are headless
   14054         if (mHeadless) return true;
   14055 
   14056         int changes = 0;
   14057 
   14058         if (values != null) {
   14059             Configuration newConfig = new Configuration(mConfiguration);
   14060             changes = newConfig.updateFrom(values);
   14061             if (changes != 0) {
   14062                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   14063                     Slog.i(TAG, "Updating configuration to: " + values);
   14064                 }
   14065 
   14066                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   14067 
   14068                 if (values.locale != null && !initLocale) {
   14069                     saveLocaleLocked(values.locale,
   14070                                      !values.locale.equals(mConfiguration.locale),
   14071                                      values.userSetLocale);
   14072                 }
   14073 
   14074                 mConfigurationSeq++;
   14075                 if (mConfigurationSeq <= 0) {
   14076                     mConfigurationSeq = 1;
   14077                 }
   14078                 newConfig.seq = mConfigurationSeq;
   14079                 mConfiguration = newConfig;
   14080                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   14081 
   14082                 final Configuration configCopy = new Configuration(mConfiguration);
   14083 
   14084                 // TODO: If our config changes, should we auto dismiss any currently
   14085                 // showing dialogs?
   14086                 mShowDialogs = shouldShowDialogs(newConfig);
   14087 
   14088                 AttributeCache ac = AttributeCache.instance();
   14089                 if (ac != null) {
   14090                     ac.updateConfiguration(configCopy);
   14091                 }
   14092 
   14093                 // Make sure all resources in our process are updated
   14094                 // right now, so that anyone who is going to retrieve
   14095                 // resource values after we return will be sure to get
   14096                 // the new ones.  This is especially important during
   14097                 // boot, where the first config change needs to guarantee
   14098                 // all resources have that config before following boot
   14099                 // code is executed.
   14100                 mSystemThread.applyConfigurationToResources(configCopy);
   14101 
   14102                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   14103                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   14104                     msg.obj = new Configuration(configCopy);
   14105                     mHandler.sendMessage(msg);
   14106                 }
   14107 
   14108                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   14109                     ProcessRecord app = mLruProcesses.get(i);
   14110                     try {
   14111                         if (app.thread != null) {
   14112                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   14113                                     + app.processName + " new config " + mConfiguration);
   14114                             app.thread.scheduleConfigurationChanged(configCopy);
   14115                         }
   14116                     } catch (Exception e) {
   14117                     }
   14118                 }
   14119                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   14120                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14121                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   14122                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14123                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   14124                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   14125                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   14126                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   14127                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   14128                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   14129                     broadcastIntentLocked(null, null, intent,
   14130                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14131                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14132                 }
   14133             }
   14134         }
   14135 
   14136         boolean kept = true;
   14137         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   14138         if (changes != 0 && starting == null) {
   14139             // If the configuration changed, and the caller is not already
   14140             // in the process of starting an activity, then find the top
   14141             // activity to check if its configuration needs to change.
   14142             starting = mainStack.topRunningActivityLocked(null);
   14143         }
   14144 
   14145         if (starting != null) {
   14146             kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   14147             // And we need to make sure at this point that all other activities
   14148             // are made visible with the correct configuration.
   14149             mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   14150         }
   14151 
   14152         if (values != null && mWindowManager != null) {
   14153             mWindowManager.setNewConfiguration(mConfiguration);
   14154         }
   14155 
   14156         return kept;
   14157     }
   14158 
   14159     /**
   14160      * Decide based on the configuration whether we should shouw the ANR,
   14161      * crash, etc dialogs.  The idea is that if there is no affordnace to
   14162      * press the on-screen buttons, we shouldn't show the dialog.
   14163      *
   14164      * A thought: SystemUI might also want to get told about this, the Power
   14165      * dialog / global actions also might want different behaviors.
   14166      */
   14167     private static final boolean shouldShowDialogs(Configuration config) {
   14168         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   14169                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   14170     }
   14171 
   14172     /**
   14173      * Save the locale.  You must be inside a synchronized (this) block.
   14174      */
   14175     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   14176         if(isDiff) {
   14177             SystemProperties.set("user.language", l.getLanguage());
   14178             SystemProperties.set("user.region", l.getCountry());
   14179         }
   14180 
   14181         if(isPersist) {
   14182             SystemProperties.set("persist.sys.language", l.getLanguage());
   14183             SystemProperties.set("persist.sys.country", l.getCountry());
   14184             SystemProperties.set("persist.sys.localevar", l.getVariant());
   14185         }
   14186     }
   14187 
   14188     @Override
   14189     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   14190         ActivityRecord srec = ActivityRecord.forToken(token);
   14191         return srec != null && srec.task.affinity != null &&
   14192                 srec.task.affinity.equals(destAffinity);
   14193     }
   14194 
   14195     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   14196             Intent resultData) {
   14197 
   14198         synchronized (this) {
   14199             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   14200             if (stack != null) {
   14201                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   14202             }
   14203             return false;
   14204         }
   14205     }
   14206 
   14207     public int getLaunchedFromUid(IBinder activityToken) {
   14208         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   14209         if (srec == null) {
   14210             return -1;
   14211         }
   14212         return srec.launchedFromUid;
   14213     }
   14214 
   14215     public String getLaunchedFromPackage(IBinder activityToken) {
   14216         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   14217         if (srec == null) {
   14218             return null;
   14219         }
   14220         return srec.launchedFromPackage;
   14221     }
   14222 
   14223     // =========================================================
   14224     // LIFETIME MANAGEMENT
   14225     // =========================================================
   14226 
   14227     // Returns which broadcast queue the app is the current [or imminent] receiver
   14228     // on, or 'null' if the app is not an active broadcast recipient.
   14229     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   14230         BroadcastRecord r = app.curReceiver;
   14231         if (r != null) {
   14232             return r.queue;
   14233         }
   14234 
   14235         // It's not the current receiver, but it might be starting up to become one
   14236         synchronized (this) {
   14237             for (BroadcastQueue queue : mBroadcastQueues) {
   14238                 r = queue.mPendingBroadcast;
   14239                 if (r != null && r.curApp == app) {
   14240                     // found it; report which queue it's in
   14241                     return queue;
   14242                 }
   14243             }
   14244         }
   14245 
   14246         return null;
   14247     }
   14248 
   14249     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   14250             boolean doingAll, long now) {
   14251         if (mAdjSeq == app.adjSeq) {
   14252             // This adjustment has already been computed.
   14253             return app.curRawAdj;
   14254         }
   14255 
   14256         if (app.thread == null) {
   14257             app.adjSeq = mAdjSeq;
   14258             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14259             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14260             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   14261         }
   14262 
   14263         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   14264         app.adjSource = null;
   14265         app.adjTarget = null;
   14266         app.empty = false;
   14267         app.cached = false;
   14268 
   14269         final int activitiesSize = app.activities.size();
   14270 
   14271         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14272             // The max adjustment doesn't allow this app to be anything
   14273             // below foreground, so it is not worth doing work for it.
   14274             app.adjType = "fixed";
   14275             app.adjSeq = mAdjSeq;
   14276             app.curRawAdj = app.maxAdj;
   14277             app.foregroundActivities = false;
   14278             app.keeping = true;
   14279             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   14280             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   14281             // System process can do UI, and when they do we want to have
   14282             // them trim their memory after the user leaves the UI.  To
   14283             // facilitate this, here we need to determine whether or not it
   14284             // is currently showing UI.
   14285             app.systemNoUi = true;
   14286             if (app == TOP_APP) {
   14287                 app.systemNoUi = false;
   14288             } else if (activitiesSize > 0) {
   14289                 for (int j = 0; j < activitiesSize; j++) {
   14290                     final ActivityRecord r = app.activities.get(j);
   14291                     if (r.visible) {
   14292                         app.systemNoUi = false;
   14293                     }
   14294                 }
   14295             }
   14296             if (!app.systemNoUi) {
   14297                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   14298             }
   14299             return (app.curAdj=app.maxAdj);
   14300         }
   14301 
   14302         app.keeping = false;
   14303         app.systemNoUi = false;
   14304 
   14305         // Determine the importance of the process, starting with most
   14306         // important to least, and assign an appropriate OOM adjustment.
   14307         int adj;
   14308         int schedGroup;
   14309         int procState;
   14310         boolean foregroundActivities = false;
   14311         boolean interesting = false;
   14312         BroadcastQueue queue;
   14313         if (app == TOP_APP) {
   14314             // The last app on the list is the foreground app.
   14315             adj = ProcessList.FOREGROUND_APP_ADJ;
   14316             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14317             app.adjType = "top-activity";
   14318             foregroundActivities = true;
   14319             interesting = true;
   14320             procState = ActivityManager.PROCESS_STATE_TOP;
   14321         } else if (app.instrumentationClass != null) {
   14322             // Don't want to kill running instrumentation.
   14323             adj = ProcessList.FOREGROUND_APP_ADJ;
   14324             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14325             app.adjType = "instrumentation";
   14326             interesting = true;
   14327             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14328         } else if ((queue = isReceivingBroadcast(app)) != null) {
   14329             // An app that is currently receiving a broadcast also
   14330             // counts as being in the foreground for OOM killer purposes.
   14331             // It's placed in a sched group based on the nature of the
   14332             // broadcast as reflected by which queue it's active in.
   14333             adj = ProcessList.FOREGROUND_APP_ADJ;
   14334             schedGroup = (queue == mFgBroadcastQueue)
   14335                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14336             app.adjType = "broadcast";
   14337             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   14338         } else if (app.executingServices.size() > 0) {
   14339             // An app that is currently executing a service callback also
   14340             // counts as being in the foreground.
   14341             adj = ProcessList.FOREGROUND_APP_ADJ;
   14342             schedGroup = app.execServicesFg ?
   14343                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14344             app.adjType = "exec-service";
   14345             procState = ActivityManager.PROCESS_STATE_SERVICE;
   14346             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   14347         } else {
   14348             // As far as we know the process is empty.  We may change our mind later.
   14349             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14350             // At this point we don't actually know the adjustment.  Use the cached adj
   14351             // value that the caller wants us to.
   14352             adj = cachedAdj;
   14353             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14354             app.cached = true;
   14355             app.empty = true;
   14356             app.adjType = "cch-empty";
   14357         }
   14358 
   14359         // Examine all activities if not already foreground.
   14360         if (!foregroundActivities && activitiesSize > 0) {
   14361             for (int j = 0; j < activitiesSize; j++) {
   14362                 final ActivityRecord r = app.activities.get(j);
   14363                 if (r.app != app) {
   14364                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   14365                             + app + "?!?");
   14366                     continue;
   14367                 }
   14368                 if (r.visible) {
   14369                     // App has a visible activity; only upgrade adjustment.
   14370                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14371                         adj = ProcessList.VISIBLE_APP_ADJ;
   14372                         app.adjType = "visible";
   14373                     }
   14374                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14375                         procState = ActivityManager.PROCESS_STATE_TOP;
   14376                     }
   14377                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14378                     app.cached = false;
   14379                     app.empty = false;
   14380                     foregroundActivities = true;
   14381                     break;
   14382                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   14383                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14384                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14385                         app.adjType = "pausing";
   14386                     }
   14387                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14388                         procState = ActivityManager.PROCESS_STATE_TOP;
   14389                     }
   14390                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14391                     app.cached = false;
   14392                     app.empty = false;
   14393                     foregroundActivities = true;
   14394                 } else if (r.state == ActivityState.STOPPING) {
   14395                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14396                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14397                         app.adjType = "stopping";
   14398                     }
   14399                     // For the process state, we will at this point consider the
   14400                     // process to be cached.  It will be cached either as an activity
   14401                     // or empty depending on whether the activity is finishing.  We do
   14402                     // this so that we can treat the process as cached for purposes of
   14403                     // memory trimming (determing current memory level, trim command to
   14404                     // send to process) since there can be an arbitrary number of stopping
   14405                     // processes and they should soon all go into the cached state.
   14406                     if (!r.finishing) {
   14407                         if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14408                             procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14409                         }
   14410                     }
   14411                     app.cached = false;
   14412                     app.empty = false;
   14413                     foregroundActivities = true;
   14414                 } else {
   14415                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14416                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14417                         app.adjType = "cch-act";
   14418                     }
   14419                 }
   14420             }
   14421         }
   14422 
   14423         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14424             if (app.foregroundServices) {
   14425                 // The user is aware of this app, so make it visible.
   14426                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14427                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14428                 app.cached = false;
   14429                 app.adjType = "fg-service";
   14430                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14431             } else if (app.forcingToForeground != null) {
   14432                 // The user is aware of this app, so make it visible.
   14433                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14434                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14435                 app.cached = false;
   14436                 app.adjType = "force-fg";
   14437                 app.adjSource = app.forcingToForeground;
   14438                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14439             }
   14440         }
   14441 
   14442         if (app.foregroundServices) {
   14443             interesting = true;
   14444         }
   14445 
   14446         if (app == mHeavyWeightProcess) {
   14447             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14448                 // We don't want to kill the current heavy-weight process.
   14449                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   14450                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14451                 app.cached = false;
   14452                 app.adjType = "heavy";
   14453             }
   14454             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   14455                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   14456             }
   14457         }
   14458 
   14459         if (app == mHomeProcess) {
   14460             if (adj > ProcessList.HOME_APP_ADJ) {
   14461                 // This process is hosting what we currently consider to be the
   14462                 // home app, so we don't want to let it go into the background.
   14463                 adj = ProcessList.HOME_APP_ADJ;
   14464                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14465                 app.cached = false;
   14466                 app.adjType = "home";
   14467             }
   14468             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   14469                 procState = ActivityManager.PROCESS_STATE_HOME;
   14470             }
   14471         }
   14472 
   14473         if (app == mPreviousProcess && app.activities.size() > 0) {
   14474             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   14475                 // This was the previous process that showed UI to the user.
   14476                 // We want to try to keep it around more aggressively, to give
   14477                 // a good experience around switching between two apps.
   14478                 adj = ProcessList.PREVIOUS_APP_ADJ;
   14479                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14480                 app.cached = false;
   14481                 app.adjType = "previous";
   14482             }
   14483             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   14484                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   14485             }
   14486         }
   14487 
   14488         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   14489                 + " reason=" + app.adjType);
   14490 
   14491         // By default, we use the computed adjustment.  It may be changed if
   14492         // there are applications dependent on our services or providers, but
   14493         // this gives us a baseline and makes sure we don't get into an
   14494         // infinite recursion.
   14495         app.adjSeq = mAdjSeq;
   14496         app.curRawAdj = adj;
   14497         app.hasStartedServices = false;
   14498 
   14499         if (mBackupTarget != null && app == mBackupTarget.app) {
   14500             // If possible we want to avoid killing apps while they're being backed up
   14501             if (adj > ProcessList.BACKUP_APP_ADJ) {
   14502                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   14503                 adj = ProcessList.BACKUP_APP_ADJ;
   14504                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14505                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14506                 }
   14507                 app.adjType = "backup";
   14508                 app.cached = false;
   14509             }
   14510             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   14511                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   14512             }
   14513         }
   14514 
   14515         boolean mayBeTop = false;
   14516 
   14517         for (int is = app.services.size()-1;
   14518                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14519                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14520                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14521                 is--) {
   14522             ServiceRecord s = app.services.valueAt(is);
   14523             if (s.startRequested) {
   14524                 app.hasStartedServices = true;
   14525                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   14526                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   14527                 }
   14528                 if (app.hasShownUi && app != mHomeProcess) {
   14529                     // If this process has shown some UI, let it immediately
   14530                     // go to the LRU list because it may be pretty heavy with
   14531                     // UI stuff.  We'll tag it with a label just to help
   14532                     // debug and understand what is going on.
   14533                     if (adj > ProcessList.SERVICE_ADJ) {
   14534                         app.adjType = "cch-started-ui-services";
   14535                     }
   14536                 } else {
   14537                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14538                         // This service has seen some activity within
   14539                         // recent memory, so we will keep its process ahead
   14540                         // of the background processes.
   14541                         if (adj > ProcessList.SERVICE_ADJ) {
   14542                             adj = ProcessList.SERVICE_ADJ;
   14543                             app.adjType = "started-services";
   14544                             app.cached = false;
   14545                         }
   14546                     }
   14547                     // If we have let the service slide into the background
   14548                     // state, still have some text describing what it is doing
   14549                     // even though the service no longer has an impact.
   14550                     if (adj > ProcessList.SERVICE_ADJ) {
   14551                         app.adjType = "cch-started-services";
   14552                     }
   14553                 }
   14554                 // Don't kill this process because it is doing work; it
   14555                 // has said it is doing work.
   14556                 app.keeping = true;
   14557             }
   14558             for (int conni = s.connections.size()-1;
   14559                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14560                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14561                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14562                     conni--) {
   14563                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   14564                 for (int i = 0;
   14565                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   14566                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14567                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   14568                         i++) {
   14569                     // XXX should compute this based on the max of
   14570                     // all connected clients.
   14571                     ConnectionRecord cr = clist.get(i);
   14572                     if (cr.binding.client == app) {
   14573                         // Binding to ourself is not interesting.
   14574                         continue;
   14575                     }
   14576                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   14577                         ProcessRecord client = cr.binding.client;
   14578                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   14579                                 TOP_APP, doingAll, now);
   14580                         int clientProcState = client.curProcState;
   14581                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14582                             // If the other app is cached for any reason, for purposes here
   14583                             // we are going to consider it empty.  The specific cached state
   14584                             // doesn't propagate except under certain conditions.
   14585                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14586                         }
   14587                         String adjType = null;
   14588                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   14589                             // Not doing bind OOM management, so treat
   14590                             // this guy more like a started service.
   14591                             if (app.hasShownUi && app != mHomeProcess) {
   14592                                 // If this process has shown some UI, let it immediately
   14593                                 // go to the LRU list because it may be pretty heavy with
   14594                                 // UI stuff.  We'll tag it with a label just to help
   14595                                 // debug and understand what is going on.
   14596                                 if (adj > clientAdj) {
   14597                                     adjType = "cch-bound-ui-services";
   14598                                 }
   14599                                 app.cached = false;
   14600                                 clientAdj = adj;
   14601                                 clientProcState = procState;
   14602                             } else {
   14603                                 if (now >= (s.lastActivity
   14604                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14605                                     // This service has not seen activity within
   14606                                     // recent memory, so allow it to drop to the
   14607                                     // LRU list if there is no other reason to keep
   14608                                     // it around.  We'll also tag it with a label just
   14609                                     // to help debug and undertand what is going on.
   14610                                     if (adj > clientAdj) {
   14611                                         adjType = "cch-bound-services";
   14612                                     }
   14613                                     clientAdj = adj;
   14614                                 }
   14615                             }
   14616                         }
   14617                         if (adj > clientAdj) {
   14618                             // If this process has recently shown UI, and
   14619                             // the process that is binding to it is less
   14620                             // important than being visible, then we don't
   14621                             // care about the binding as much as we care
   14622                             // about letting this process get into the LRU
   14623                             // list to be killed and restarted if needed for
   14624                             // memory.
   14625                             if (app.hasShownUi && app != mHomeProcess
   14626                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14627                                 adjType = "cch-bound-ui-services";
   14628                             } else {
   14629                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   14630                                         |Context.BIND_IMPORTANT)) != 0) {
   14631                                     adj = clientAdj;
   14632                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   14633                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   14634                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14635                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14636                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   14637                                     adj = clientAdj;
   14638                                 } else {
   14639                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14640                                         adj = ProcessList.VISIBLE_APP_ADJ;
   14641                                     }
   14642                                 }
   14643                                 if (!client.cached) {
   14644                                     app.cached = false;
   14645                                 }
   14646                                 if (client.keeping) {
   14647                                     app.keeping = true;
   14648                                 }
   14649                                 adjType = "service";
   14650                             }
   14651                         }
   14652                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14653                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14654                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14655                             }
   14656                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14657                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14658                                     // Special handling of clients who are in the top state.
   14659                                     // We *may* want to consider this process to be in the
   14660                                     // top state as well, but only if there is not another
   14661                                     // reason for it to be running.  Being on the top is a
   14662                                     // special state, meaning you are specifically running
   14663                                     // for the current top app.  If the process is already
   14664                                     // running in the background for some other reason, it
   14665                                     // is more important to continue considering it to be
   14666                                     // in the background state.
   14667                                     mayBeTop = true;
   14668                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14669                                 } else {
   14670                                     // Special handling for above-top states (persistent
   14671                                     // processes).  These should not bring the current process
   14672                                     // into the top state, since they are not on top.  Instead
   14673                                     // give them the best state after that.
   14674                                     clientProcState =
   14675                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14676                                 }
   14677                             }
   14678                         } else {
   14679                             if (clientProcState <
   14680                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14681                                 clientProcState =
   14682                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14683                             }
   14684                         }
   14685                         if (procState > clientProcState) {
   14686                             procState = clientProcState;
   14687                         }
   14688                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   14689                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   14690                             app.pendingUiClean = true;
   14691                         }
   14692                         if (adjType != null) {
   14693                             app.adjType = adjType;
   14694                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14695                                     .REASON_SERVICE_IN_USE;
   14696                             app.adjSource = cr.binding.client;
   14697                             app.adjSourceOom = clientAdj;
   14698                             app.adjTarget = s.name;
   14699                         }
   14700                     }
   14701                     final ActivityRecord a = cr.activity;
   14702                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   14703                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   14704                                 (a.visible || a.state == ActivityState.RESUMED
   14705                                  || a.state == ActivityState.PAUSING)) {
   14706                             adj = ProcessList.FOREGROUND_APP_ADJ;
   14707                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14708                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14709                             }
   14710                             app.cached = false;
   14711                             app.adjType = "service";
   14712                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14713                                     .REASON_SERVICE_IN_USE;
   14714                             app.adjSource = a;
   14715                             app.adjSourceOom = adj;
   14716                             app.adjTarget = s.name;
   14717                         }
   14718                     }
   14719                 }
   14720             }
   14721         }
   14722 
   14723         for (int provi = app.pubProviders.size()-1;
   14724                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14725                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14726                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14727                 provi--) {
   14728             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   14729             for (int i = cpr.connections.size()-1;
   14730                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14731                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14732                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14733                     i--) {
   14734                 ContentProviderConnection conn = cpr.connections.get(i);
   14735                 ProcessRecord client = conn.client;
   14736                 if (client == app) {
   14737                     // Being our own client is not interesting.
   14738                     continue;
   14739                 }
   14740                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   14741                 int clientProcState = client.curProcState;
   14742                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14743                     // If the other app is cached for any reason, for purposes here
   14744                     // we are going to consider it empty.
   14745                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14746                 }
   14747                 if (adj > clientAdj) {
   14748                     if (app.hasShownUi && app != mHomeProcess
   14749                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14750                         app.adjType = "cch-ui-provider";
   14751                     } else {
   14752                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   14753                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   14754                         app.adjType = "provider";
   14755                     }
   14756                     app.cached &= client.cached;
   14757                     app.keeping |= client.keeping;
   14758                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14759                             .REASON_PROVIDER_IN_USE;
   14760                     app.adjSource = client;
   14761                     app.adjSourceOom = clientAdj;
   14762                     app.adjTarget = cpr.name;
   14763                 }
   14764                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14765                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14766                         // Special handling of clients who are in the top state.
   14767                         // We *may* want to consider this process to be in the
   14768                         // top state as well, but only if there is not another
   14769                         // reason for it to be running.  Being on the top is a
   14770                         // special state, meaning you are specifically running
   14771                         // for the current top app.  If the process is already
   14772                         // running in the background for some other reason, it
   14773                         // is more important to continue considering it to be
   14774                         // in the background state.
   14775                         mayBeTop = true;
   14776                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14777                     } else {
   14778                         // Special handling for above-top states (persistent
   14779                         // processes).  These should not bring the current process
   14780                         // into the top state, since they are not on top.  Instead
   14781                         // give them the best state after that.
   14782                         clientProcState =
   14783                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14784                     }
   14785                 }
   14786                 if (procState > clientProcState) {
   14787                     procState = clientProcState;
   14788                 }
   14789                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14790                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14791                 }
   14792             }
   14793             // If the provider has external (non-framework) process
   14794             // dependencies, ensure that its adjustment is at least
   14795             // FOREGROUND_APP_ADJ.
   14796             if (cpr.hasExternalProcessHandles()) {
   14797                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   14798                     adj = ProcessList.FOREGROUND_APP_ADJ;
   14799                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14800                     app.cached = false;
   14801                     app.keeping = true;
   14802                     app.adjType = "provider";
   14803                     app.adjTarget = cpr.name;
   14804                 }
   14805                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   14806                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14807                 }
   14808             }
   14809         }
   14810 
   14811         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   14812             // A client of one of our services or providers is in the top state.  We
   14813             // *may* want to be in the top state, but not if we are already running in
   14814             // the background for some other reason.  For the decision here, we are going
   14815             // to pick out a few specific states that we want to remain in when a client
   14816             // is top (states that tend to be longer-term) and otherwise allow it to go
   14817             // to the top state.
   14818             switch (procState) {
   14819                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   14820                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   14821                 case ActivityManager.PROCESS_STATE_SERVICE:
   14822                     // These all are longer-term states, so pull them up to the top
   14823                     // of the background states, but not all the way to the top state.
   14824                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14825                     break;
   14826                 default:
   14827                     // Otherwise, top is a better choice, so take it.
   14828                     procState = ActivityManager.PROCESS_STATE_TOP;
   14829                     break;
   14830             }
   14831         }
   14832 
   14833         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
   14834             // This is a cached process, but with client activities.  Mark it so.
   14835             procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   14836             app.adjType = "cch-client-act";
   14837         }
   14838 
   14839         if (adj == ProcessList.SERVICE_ADJ) {
   14840             if (doingAll) {
   14841                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   14842                 mNewNumServiceProcs++;
   14843                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   14844                 if (!app.serviceb) {
   14845                     // This service isn't far enough down on the LRU list to
   14846                     // normally be a B service, but if we are low on RAM and it
   14847                     // is large we want to force it down since we would prefer to
   14848                     // keep launcher over it.
   14849                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   14850                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   14851                         app.serviceHighRam = true;
   14852                         app.serviceb = true;
   14853                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   14854                     } else {
   14855                         mNewNumAServiceProcs++;
   14856                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   14857                     }
   14858                 } else {
   14859                     app.serviceHighRam = false;
   14860                 }
   14861             }
   14862             if (app.serviceb) {
   14863                 adj = ProcessList.SERVICE_B_ADJ;
   14864             }
   14865         }
   14866 
   14867         app.curRawAdj = adj;
   14868 
   14869         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14870         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14871         if (adj > app.maxAdj) {
   14872             adj = app.maxAdj;
   14873             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14874                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14875             }
   14876         }
   14877         if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
   14878             app.keeping = true;
   14879         }
   14880 
   14881         // Do final modification to adj.  Everything we do between here and applying
   14882         // the final setAdj must be done in this function, because we will also use
   14883         // it when computing the final cached adj later.  Note that we don't need to
   14884         // worry about this for max adj above, since max adj will always be used to
   14885         // keep it out of the cached vaues.
   14886         adj = app.modifyRawOomAdj(adj);
   14887 
   14888         app.curProcState = procState;
   14889 
   14890         int importance = app.memImportance;
   14891         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   14892             app.curAdj = adj;
   14893             app.curSchedGroup = schedGroup;
   14894             if (!interesting) {
   14895                 // For this reporting, if there is not something explicitly
   14896                 // interesting in this process then we will push it to the
   14897                 // background importance.
   14898                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14899             } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14900                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14901             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   14902                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14903             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   14904                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14905             } else if (adj >= ProcessList.SERVICE_ADJ) {
   14906                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14907             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14908                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   14909             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14910                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   14911             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   14912                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   14913             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   14914                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   14915             } else {
   14916                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   14917             }
   14918         }
   14919 
   14920         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   14921         if (foregroundActivities != app.foregroundActivities) {
   14922             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   14923         }
   14924         if (changes != 0) {
   14925             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   14926             app.memImportance = importance;
   14927             app.foregroundActivities = foregroundActivities;
   14928             int i = mPendingProcessChanges.size()-1;
   14929             ProcessChangeItem item = null;
   14930             while (i >= 0) {
   14931                 item = mPendingProcessChanges.get(i);
   14932                 if (item.pid == app.pid) {
   14933                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   14934                     break;
   14935                 }
   14936                 i--;
   14937             }
   14938             if (i < 0) {
   14939                 // No existing item in pending changes; need a new one.
   14940                 final int NA = mAvailProcessChanges.size();
   14941                 if (NA > 0) {
   14942                     item = mAvailProcessChanges.remove(NA-1);
   14943                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   14944                 } else {
   14945                     item = new ProcessChangeItem();
   14946                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   14947                 }
   14948                 item.changes = 0;
   14949                 item.pid = app.pid;
   14950                 item.uid = app.info.uid;
   14951                 if (mPendingProcessChanges.size() == 0) {
   14952                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   14953                             "*** Enqueueing dispatch processes changed!");
   14954                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   14955                 }
   14956                 mPendingProcessChanges.add(item);
   14957             }
   14958             item.changes |= changes;
   14959             item.importance = importance;
   14960             item.foregroundActivities = foregroundActivities;
   14961             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   14962                     + Integer.toHexString(System.identityHashCode(item))
   14963                     + " " + app.toShortString() + ": changes=" + item.changes
   14964                     + " importance=" + item.importance
   14965                     + " foreground=" + item.foregroundActivities
   14966                     + " type=" + app.adjType + " source=" + app.adjSource
   14967                     + " target=" + app.adjTarget);
   14968         }
   14969 
   14970         return app.curRawAdj;
   14971     }
   14972 
   14973     /**
   14974      * Schedule PSS collection of a process.
   14975      */
   14976     void requestPssLocked(ProcessRecord proc, int procState) {
   14977         if (mPendingPssProcesses.contains(proc)) {
   14978             return;
   14979         }
   14980         if (mPendingPssProcesses.size() == 0) {
   14981             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   14982         }
   14983         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   14984         proc.pssProcState = procState;
   14985         mPendingPssProcesses.add(proc);
   14986     }
   14987 
   14988     /**
   14989      * Schedule PSS collection of all processes.
   14990      */
   14991     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   14992         if (!always) {
   14993             if (now < (mLastFullPssTime +
   14994                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   14995                 return;
   14996             }
   14997         }
   14998         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   14999         mLastFullPssTime = now;
   15000         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   15001         mPendingPssProcesses.clear();
   15002         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   15003             ProcessRecord app = mLruProcesses.get(i);
   15004             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   15005                 app.pssProcState = app.setProcState;
   15006                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   15007                         mSleeping, now);
   15008                 mPendingPssProcesses.add(app);
   15009             }
   15010         }
   15011         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   15012     }
   15013 
   15014     /**
   15015      * Ask a given process to GC right now.
   15016      */
   15017     final void performAppGcLocked(ProcessRecord app) {
   15018         try {
   15019             app.lastRequestedGc = SystemClock.uptimeMillis();
   15020             if (app.thread != null) {
   15021                 if (app.reportLowMemory) {
   15022                     app.reportLowMemory = false;
   15023                     app.thread.scheduleLowMemory();
   15024                 } else {
   15025                     app.thread.processInBackground();
   15026                 }
   15027             }
   15028         } catch (Exception e) {
   15029             // whatever.
   15030         }
   15031     }
   15032 
   15033     /**
   15034      * Returns true if things are idle enough to perform GCs.
   15035      */
   15036     private final boolean canGcNowLocked() {
   15037         boolean processingBroadcasts = false;
   15038         for (BroadcastQueue q : mBroadcastQueues) {
   15039             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   15040                 processingBroadcasts = true;
   15041             }
   15042         }
   15043         return !processingBroadcasts
   15044                 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
   15045     }
   15046 
   15047     /**
   15048      * Perform GCs on all processes that are waiting for it, but only
   15049      * if things are idle.
   15050      */
   15051     final void performAppGcsLocked() {
   15052         final int N = mProcessesToGc.size();
   15053         if (N <= 0) {
   15054             return;
   15055         }
   15056         if (canGcNowLocked()) {
   15057             while (mProcessesToGc.size() > 0) {
   15058                 ProcessRecord proc = mProcessesToGc.remove(0);
   15059                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   15060                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   15061                             <= SystemClock.uptimeMillis()) {
   15062                         // To avoid spamming the system, we will GC processes one
   15063                         // at a time, waiting a few seconds between each.
   15064                         performAppGcLocked(proc);
   15065                         scheduleAppGcsLocked();
   15066                         return;
   15067                     } else {
   15068                         // It hasn't been long enough since we last GCed this
   15069                         // process...  put it in the list to wait for its time.
   15070                         addProcessToGcListLocked(proc);
   15071                         break;
   15072                     }
   15073                 }
   15074             }
   15075 
   15076             scheduleAppGcsLocked();
   15077         }
   15078     }
   15079 
   15080     /**
   15081      * If all looks good, perform GCs on all processes waiting for them.
   15082      */
   15083     final void performAppGcsIfAppropriateLocked() {
   15084         if (canGcNowLocked()) {
   15085             performAppGcsLocked();
   15086             return;
   15087         }
   15088         // Still not idle, wait some more.
   15089         scheduleAppGcsLocked();
   15090     }
   15091 
   15092     /**
   15093      * Schedule the execution of all pending app GCs.
   15094      */
   15095     final void scheduleAppGcsLocked() {
   15096         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   15097 
   15098         if (mProcessesToGc.size() > 0) {
   15099             // Schedule a GC for the time to the next process.
   15100             ProcessRecord proc = mProcessesToGc.get(0);
   15101             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   15102 
   15103             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   15104             long now = SystemClock.uptimeMillis();
   15105             if (when < (now+GC_TIMEOUT)) {
   15106                 when = now + GC_TIMEOUT;
   15107             }
   15108             mHandler.sendMessageAtTime(msg, when);
   15109         }
   15110     }
   15111 
   15112     /**
   15113      * Add a process to the array of processes waiting to be GCed.  Keeps the
   15114      * list in sorted order by the last GC time.  The process can't already be
   15115      * on the list.
   15116      */
   15117     final void addProcessToGcListLocked(ProcessRecord proc) {
   15118         boolean added = false;
   15119         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   15120             if (mProcessesToGc.get(i).lastRequestedGc <
   15121                     proc.lastRequestedGc) {
   15122                 added = true;
   15123                 mProcessesToGc.add(i+1, proc);
   15124                 break;
   15125             }
   15126         }
   15127         if (!added) {
   15128             mProcessesToGc.add(0, proc);
   15129         }
   15130     }
   15131 
   15132     /**
   15133      * Set up to ask a process to GC itself.  This will either do it
   15134      * immediately, or put it on the list of processes to gc the next
   15135      * time things are idle.
   15136      */
   15137     final void scheduleAppGcLocked(ProcessRecord app) {
   15138         long now = SystemClock.uptimeMillis();
   15139         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   15140             return;
   15141         }
   15142         if (!mProcessesToGc.contains(app)) {
   15143             addProcessToGcListLocked(app);
   15144             scheduleAppGcsLocked();
   15145         }
   15146     }
   15147 
   15148     final void checkExcessivePowerUsageLocked(boolean doKills) {
   15149         updateCpuStatsNow();
   15150 
   15151         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15152         boolean doWakeKills = doKills;
   15153         boolean doCpuKills = doKills;
   15154         if (mLastPowerCheckRealtime == 0) {
   15155             doWakeKills = false;
   15156         }
   15157         if (mLastPowerCheckUptime == 0) {
   15158             doCpuKills = false;
   15159         }
   15160         if (stats.isScreenOn()) {
   15161             doWakeKills = false;
   15162         }
   15163         final long curRealtime = SystemClock.elapsedRealtime();
   15164         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   15165         final long curUptime = SystemClock.uptimeMillis();
   15166         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   15167         mLastPowerCheckRealtime = curRealtime;
   15168         mLastPowerCheckUptime = curUptime;
   15169         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   15170             doWakeKills = false;
   15171         }
   15172         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   15173             doCpuKills = false;
   15174         }
   15175         int i = mLruProcesses.size();
   15176         while (i > 0) {
   15177             i--;
   15178             ProcessRecord app = mLruProcesses.get(i);
   15179             if (!app.keeping) {
   15180                 long wtime;
   15181                 synchronized (stats) {
   15182                     wtime = stats.getProcessWakeTime(app.info.uid,
   15183                             app.pid, curRealtime);
   15184                 }
   15185                 long wtimeUsed = wtime - app.lastWakeTime;
   15186                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   15187                 if (DEBUG_POWER) {
   15188                     StringBuilder sb = new StringBuilder(128);
   15189                     sb.append("Wake for ");
   15190                     app.toShortString(sb);
   15191                     sb.append(": over ");
   15192                     TimeUtils.formatDuration(realtimeSince, sb);
   15193                     sb.append(" used ");
   15194                     TimeUtils.formatDuration(wtimeUsed, sb);
   15195                     sb.append(" (");
   15196                     sb.append((wtimeUsed*100)/realtimeSince);
   15197                     sb.append("%)");
   15198                     Slog.i(TAG, sb.toString());
   15199                     sb.setLength(0);
   15200                     sb.append("CPU for ");
   15201                     app.toShortString(sb);
   15202                     sb.append(": over ");
   15203                     TimeUtils.formatDuration(uptimeSince, sb);
   15204                     sb.append(" used ");
   15205                     TimeUtils.formatDuration(cputimeUsed, sb);
   15206                     sb.append(" (");
   15207                     sb.append((cputimeUsed*100)/uptimeSince);
   15208                     sb.append("%)");
   15209                     Slog.i(TAG, sb.toString());
   15210                 }
   15211                 // If a process has held a wake lock for more
   15212                 // than 50% of the time during this period,
   15213                 // that sounds bad.  Kill!
   15214                 if (doWakeKills && realtimeSince > 0
   15215                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   15216                     synchronized (stats) {
   15217                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   15218                                 realtimeSince, wtimeUsed);
   15219                     }
   15220                     killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
   15221                             + " during " + realtimeSince);
   15222                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   15223                 } else if (doCpuKills && uptimeSince > 0
   15224                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   15225                     synchronized (stats) {
   15226                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   15227                                 uptimeSince, cputimeUsed);
   15228                     }
   15229                     killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
   15230                             + " during " + uptimeSince);
   15231                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   15232                 } else {
   15233                     app.lastWakeTime = wtime;
   15234                     app.lastCpuTime = app.curCpuTime;
   15235                 }
   15236             }
   15237         }
   15238     }
   15239 
   15240     private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
   15241             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15242         boolean success = true;
   15243 
   15244         if (app.curRawAdj != app.setRawAdj) {
   15245             if (wasKeeping && !app.keeping) {
   15246                 // This app is no longer something we want to keep.  Note
   15247                 // its current wake lock time to later know to kill it if
   15248                 // it is not behaving well.
   15249                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15250                 synchronized (stats) {
   15251                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   15252                             app.pid, SystemClock.elapsedRealtime());
   15253                 }
   15254                 app.lastCpuTime = app.curCpuTime;
   15255             }
   15256 
   15257             app.setRawAdj = app.curRawAdj;
   15258         }
   15259 
   15260         if (app.curAdj != app.setAdj) {
   15261             if (Process.setOomAdj(app.pid, app.curAdj)) {
   15262                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   15263                     TAG, "Set " + app.pid + " " + app.processName +
   15264                     " adj " + app.curAdj + ": " + app.adjType);
   15265                 app.setAdj = app.curAdj;
   15266             } else {
   15267                 success = false;
   15268                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   15269             }
   15270         }
   15271         if (app.setSchedGroup != app.curSchedGroup) {
   15272             app.setSchedGroup = app.curSchedGroup;
   15273             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15274                     "Setting process group of " + app.processName
   15275                     + " to " + app.curSchedGroup);
   15276             if (app.waitingToKill != null &&
   15277                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   15278                 killUnneededProcessLocked(app, app.waitingToKill);
   15279                 success = false;
   15280             } else {
   15281                 if (true) {
   15282                     long oldId = Binder.clearCallingIdentity();
   15283                     try {
   15284                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   15285                     } catch (Exception e) {
   15286                         Slog.w(TAG, "Failed setting process group of " + app.pid
   15287                                 + " to " + app.curSchedGroup);
   15288                         e.printStackTrace();
   15289                     } finally {
   15290                         Binder.restoreCallingIdentity(oldId);
   15291                     }
   15292                 } else {
   15293                     if (app.thread != null) {
   15294                         try {
   15295                             app.thread.setSchedulingGroup(app.curSchedGroup);
   15296                         } catch (RemoteException e) {
   15297                         }
   15298                     }
   15299                 }
   15300                 Process.setSwappiness(app.pid,
   15301                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   15302             }
   15303         }
   15304         if (app.repProcState != app.curProcState) {
   15305             app.repProcState = app.curProcState;
   15306             if (!reportingProcessState && app.thread != null) {
   15307                 try {
   15308                     if (false) {
   15309                         //RuntimeException h = new RuntimeException("here");
   15310                         Slog.i(TAG, "Sending new process state " + app.repProcState
   15311                                 + " to " + app /*, h*/);
   15312                     }
   15313                     app.thread.setProcessState(app.repProcState);
   15314                 } catch (RemoteException e) {
   15315                 }
   15316             }
   15317         }
   15318         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   15319                 app.setProcState)) {
   15320             app.lastStateTime = now;
   15321             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   15322                     mSleeping, now);
   15323             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   15324                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   15325                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   15326                     + (app.nextPssTime-now) + ": " + app);
   15327         } else {
   15328             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   15329                     && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
   15330                 requestPssLocked(app, app.setProcState);
   15331                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   15332                         mSleeping, now);
   15333             } else if (false && DEBUG_PSS) {
   15334                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   15335             }
   15336         }
   15337         if (app.setProcState != app.curProcState) {
   15338             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15339                     "Proc state change of " + app.processName
   15340                     + " to " + app.curProcState);
   15341             app.setProcState = app.curProcState;
   15342             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   15343                 app.notCachedSinceIdle = false;
   15344             }
   15345             if (!doingAll) {
   15346                 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
   15347             } else {
   15348                 app.procStateChanged = true;
   15349             }
   15350         }
   15351         return success;
   15352     }
   15353 
   15354     private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
   15355         if (proc.thread != null && proc.baseProcessTracker != null) {
   15356             proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   15357         }
   15358     }
   15359 
   15360     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   15361             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15362         if (app.thread == null) {
   15363             return false;
   15364         }
   15365 
   15366         final boolean wasKeeping = app.keeping;
   15367 
   15368         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   15369 
   15370         return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
   15371                 reportingProcessState, now);
   15372     }
   15373 
   15374     private final ActivityRecord resumedAppLocked() {
   15375         return mStackSupervisor.resumedAppLocked();
   15376     }
   15377 
   15378     final boolean updateOomAdjLocked(ProcessRecord app) {
   15379         return updateOomAdjLocked(app, false);
   15380     }
   15381 
   15382     final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
   15383         final ActivityRecord TOP_ACT = resumedAppLocked();
   15384         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15385         final boolean wasCached = app.cached;
   15386 
   15387         mAdjSeq++;
   15388 
   15389         // This is the desired cached adjusment we want to tell it to use.
   15390         // If our app is currently cached, we know it, and that is it.  Otherwise,
   15391         // we don't know it yet, and it needs to now be cached we will then
   15392         // need to do a complete oom adj.
   15393         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   15394                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   15395         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
   15396                 SystemClock.uptimeMillis());
   15397         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   15398             // Changed to/from cached state, so apps after it in the LRU
   15399             // list may also be changed.
   15400             updateOomAdjLocked();
   15401         }
   15402         return success;
   15403     }
   15404 
   15405     final void updateOomAdjLocked() {
   15406         final ActivityRecord TOP_ACT = resumedAppLocked();
   15407         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15408         final long now = SystemClock.uptimeMillis();
   15409         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   15410         final int N = mLruProcesses.size();
   15411 
   15412         if (false) {
   15413             RuntimeException e = new RuntimeException();
   15414             e.fillInStackTrace();
   15415             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   15416         }
   15417 
   15418         mAdjSeq++;
   15419         mNewNumServiceProcs = 0;
   15420         mNewNumAServiceProcs = 0;
   15421 
   15422         final int emptyProcessLimit;
   15423         final int cachedProcessLimit;
   15424         if (mProcessLimit <= 0) {
   15425             emptyProcessLimit = cachedProcessLimit = 0;
   15426         } else if (mProcessLimit == 1) {
   15427             emptyProcessLimit = 1;
   15428             cachedProcessLimit = 0;
   15429         } else {
   15430             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   15431             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   15432         }
   15433 
   15434         // Let's determine how many processes we have running vs.
   15435         // how many slots we have for background processes; we may want
   15436         // to put multiple processes in a slot of there are enough of
   15437         // them.
   15438         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   15439                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   15440         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   15441         if (numEmptyProcs > cachedProcessLimit) {
   15442             // If there are more empty processes than our limit on cached
   15443             // processes, then use the cached process limit for the factor.
   15444             // This ensures that the really old empty processes get pushed
   15445             // down to the bottom, so if we are running low on memory we will
   15446             // have a better chance at keeping around more cached processes
   15447             // instead of a gazillion empty processes.
   15448             numEmptyProcs = cachedProcessLimit;
   15449         }
   15450         int emptyFactor = numEmptyProcs/numSlots;
   15451         if (emptyFactor < 1) emptyFactor = 1;
   15452         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   15453         if (cachedFactor < 1) cachedFactor = 1;
   15454         int stepCached = 0;
   15455         int stepEmpty = 0;
   15456         int numCached = 0;
   15457         int numEmpty = 0;
   15458         int numTrimming = 0;
   15459 
   15460         mNumNonCachedProcs = 0;
   15461         mNumCachedHiddenProcs = 0;
   15462 
   15463         // First update the OOM adjustment for each of the
   15464         // application processes based on their current state.
   15465         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15466         int nextCachedAdj = curCachedAdj+1;
   15467         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15468         int nextEmptyAdj = curEmptyAdj+2;
   15469         for (int i=N-1; i>=0; i--) {
   15470             ProcessRecord app = mLruProcesses.get(i);
   15471             if (!app.killedByAm && app.thread != null) {
   15472                 app.procStateChanged = false;
   15473                 final boolean wasKeeping = app.keeping;
   15474                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   15475 
   15476                 // If we haven't yet assigned the final cached adj
   15477                 // to the process, do that now.
   15478                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   15479                     switch (app.curProcState) {
   15480                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15481                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15482                             // This process is a cached process holding activities...
   15483                             // assign it the next cached value for that type, and then
   15484                             // step that cached level.
   15485                             app.curRawAdj = curCachedAdj;
   15486                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   15487                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
   15488                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   15489                                     + ")");
   15490                             if (curCachedAdj != nextCachedAdj) {
   15491                                 stepCached++;
   15492                                 if (stepCached >= cachedFactor) {
   15493                                     stepCached = 0;
   15494                                     curCachedAdj = nextCachedAdj;
   15495                                     nextCachedAdj += 2;
   15496                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15497                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15498                                     }
   15499                                 }
   15500                             }
   15501                             break;
   15502                         default:
   15503                             // For everything else, assign next empty cached process
   15504                             // level and bump that up.  Note that this means that
   15505                             // long-running services that have dropped down to the
   15506                             // cached level will be treated as empty (since their process
   15507                             // state is still as a service), which is what we want.
   15508                             app.curRawAdj = curEmptyAdj;
   15509                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   15510                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
   15511                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   15512                                     + ")");
   15513                             if (curEmptyAdj != nextEmptyAdj) {
   15514                                 stepEmpty++;
   15515                                 if (stepEmpty >= emptyFactor) {
   15516                                     stepEmpty = 0;
   15517                                     curEmptyAdj = nextEmptyAdj;
   15518                                     nextEmptyAdj += 2;
   15519                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15520                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15521                                     }
   15522                                 }
   15523                             }
   15524                             break;
   15525                     }
   15526                 }
   15527 
   15528                 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
   15529 
   15530                 // Count the number of process types.
   15531                 switch (app.curProcState) {
   15532                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15533                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15534                         mNumCachedHiddenProcs++;
   15535                         numCached++;
   15536                         if (numCached > cachedProcessLimit) {
   15537                             killUnneededProcessLocked(app, "cached #" + numCached);
   15538                         }
   15539                         break;
   15540                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   15541                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   15542                                 && app.lastActivityTime < oldTime) {
   15543                             killUnneededProcessLocked(app, "empty for "
   15544                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   15545                                     / 1000) + "s");
   15546                         } else {
   15547                             numEmpty++;
   15548                             if (numEmpty > emptyProcessLimit) {
   15549                                 killUnneededProcessLocked(app, "empty #" + numEmpty);
   15550                             }
   15551                         }
   15552                         break;
   15553                     default:
   15554                         mNumNonCachedProcs++;
   15555                         break;
   15556                 }
   15557 
   15558                 if (app.isolated && app.services.size() <= 0) {
   15559                     // If this is an isolated process, and there are no
   15560                     // services running in it, then the process is no longer
   15561                     // needed.  We agressively kill these because we can by
   15562                     // definition not re-use the same process again, and it is
   15563                     // good to avoid having whatever code was running in them
   15564                     // left sitting around after no longer needed.
   15565                     killUnneededProcessLocked(app, "isolated not needed");
   15566                 }
   15567 
   15568                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15569                         && !app.killedByAm) {
   15570                     numTrimming++;
   15571                 }
   15572             }
   15573         }
   15574 
   15575         mNumServiceProcs = mNewNumServiceProcs;
   15576 
   15577         // Now determine the memory trimming level of background processes.
   15578         // Unfortunately we need to start at the back of the list to do this
   15579         // properly.  We only do this if the number of background apps we
   15580         // are managing to keep around is less than half the maximum we desire;
   15581         // if we are keeping a good number around, we'll let them use whatever
   15582         // memory they want.
   15583         final int numCachedAndEmpty = numCached + numEmpty;
   15584         int memFactor;
   15585         if (numCached <= ProcessList.TRIM_CACHED_APPS
   15586                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   15587             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   15588                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   15589             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   15590                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   15591             } else {
   15592                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   15593             }
   15594         } else {
   15595             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   15596         }
   15597         // We always allow the memory level to go up (better).  We only allow it to go
   15598         // down if we are in a state where that is allowed, *and* the total number of processes
   15599         // has gone down since last time.
   15600         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   15601                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   15602                 + " last=" + mLastNumProcesses);
   15603         if (memFactor > mLastMemoryLevel) {
   15604             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   15605                 memFactor = mLastMemoryLevel;
   15606                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   15607             }
   15608         }
   15609         mLastMemoryLevel = memFactor;
   15610         mLastNumProcesses = mLruProcesses.size();
   15611         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
   15612         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   15613         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   15614             if (mLowRamStartTime == 0) {
   15615                 mLowRamStartTime = now;
   15616             }
   15617             int step = 0;
   15618             int fgTrimLevel;
   15619             switch (memFactor) {
   15620                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   15621                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   15622                     break;
   15623                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   15624                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   15625                     break;
   15626                 default:
   15627                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   15628                     break;
   15629             }
   15630             int factor = numTrimming/3;
   15631             int minFactor = 2;
   15632             if (mHomeProcess != null) minFactor++;
   15633             if (mPreviousProcess != null) minFactor++;
   15634             if (factor < minFactor) factor = minFactor;
   15635             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   15636             for (int i=N-1; i>=0; i--) {
   15637                 ProcessRecord app = mLruProcesses.get(i);
   15638                 if (allChanged || app.procStateChanged) {
   15639                     setProcessTrackerState(app, trackerMemFactor, now);
   15640                     app.procStateChanged = false;
   15641                 }
   15642                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15643                         && !app.killedByAm) {
   15644                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   15645                         try {
   15646                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15647                                     "Trimming memory of " + app.processName
   15648                                     + " to " + curLevel);
   15649                             app.thread.scheduleTrimMemory(curLevel);
   15650                         } catch (RemoteException e) {
   15651                         }
   15652                         if (false) {
   15653                             // For now we won't do this; our memory trimming seems
   15654                             // to be good enough at this point that destroying
   15655                             // activities causes more harm than good.
   15656                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   15657                                     && app != mHomeProcess && app != mPreviousProcess) {
   15658                                 // Need to do this on its own message because the stack may not
   15659                                 // be in a consistent state at this point.
   15660                                 // For these apps we will also finish their activities
   15661                                 // to help them free memory.
   15662                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   15663                             }
   15664                         }
   15665                     }
   15666                     app.trimMemoryLevel = curLevel;
   15667                     step++;
   15668                     if (step >= factor) {
   15669                         step = 0;
   15670                         switch (curLevel) {
   15671                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   15672                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   15673                                 break;
   15674                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   15675                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15676                                 break;
   15677                         }
   15678                     }
   15679                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   15680                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   15681                             && app.thread != null) {
   15682                         try {
   15683                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15684                                     "Trimming memory of heavy-weight " + app.processName
   15685                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15686                             app.thread.scheduleTrimMemory(
   15687                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15688                         } catch (RemoteException e) {
   15689                         }
   15690                     }
   15691                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15692                 } else {
   15693                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15694                             || app.systemNoUi) && app.pendingUiClean) {
   15695                         // If this application is now in the background and it
   15696                         // had done UI, then give it the special trim level to
   15697                         // have it free UI resources.
   15698                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   15699                         if (app.trimMemoryLevel < level && app.thread != null) {
   15700                             try {
   15701                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15702                                         "Trimming memory of bg-ui " + app.processName
   15703                                         + " to " + level);
   15704                                 app.thread.scheduleTrimMemory(level);
   15705                             } catch (RemoteException e) {
   15706                             }
   15707                         }
   15708                         app.pendingUiClean = false;
   15709                     }
   15710                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   15711                         try {
   15712                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15713                                     "Trimming memory of fg " + app.processName
   15714                                     + " to " + fgTrimLevel);
   15715                             app.thread.scheduleTrimMemory(fgTrimLevel);
   15716                         } catch (RemoteException e) {
   15717                         }
   15718                     }
   15719                     app.trimMemoryLevel = fgTrimLevel;
   15720                 }
   15721             }
   15722         } else {
   15723             if (mLowRamStartTime != 0) {
   15724                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   15725                 mLowRamStartTime = 0;
   15726             }
   15727             for (int i=N-1; i>=0; i--) {
   15728                 ProcessRecord app = mLruProcesses.get(i);
   15729                 if (allChanged || app.procStateChanged) {
   15730                     setProcessTrackerState(app, trackerMemFactor, now);
   15731                     app.procStateChanged = false;
   15732                 }
   15733                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15734                         || app.systemNoUi) && app.pendingUiClean) {
   15735                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   15736                             && app.thread != null) {
   15737                         try {
   15738                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15739                                     "Trimming memory of ui hidden " + app.processName
   15740                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15741                             app.thread.scheduleTrimMemory(
   15742                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15743                         } catch (RemoteException e) {
   15744                         }
   15745                     }
   15746                     app.pendingUiClean = false;
   15747                 }
   15748                 app.trimMemoryLevel = 0;
   15749             }
   15750         }
   15751 
   15752         if (mAlwaysFinishActivities) {
   15753             // Need to do this on its own message because the stack may not
   15754             // be in a consistent state at this point.
   15755             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   15756         }
   15757 
   15758         if (allChanged) {
   15759             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   15760         }
   15761 
   15762         if (mProcessStats.shouldWriteNowLocked(now)) {
   15763             mHandler.post(new Runnable() {
   15764                 @Override public void run() {
   15765                     synchronized (ActivityManagerService.this) {
   15766                         mProcessStats.writeStateAsyncLocked();
   15767                     }
   15768                 }
   15769             });
   15770         }
   15771 
   15772         if (DEBUG_OOM_ADJ) {
   15773             Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   15774         }
   15775     }
   15776 
   15777     final void trimApplications() {
   15778         synchronized (this) {
   15779             int i;
   15780 
   15781             // First remove any unused application processes whose package
   15782             // has been removed.
   15783             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   15784                 final ProcessRecord app = mRemovedProcesses.get(i);
   15785                 if (app.activities.size() == 0
   15786                         && app.curReceiver == null && app.services.size() == 0) {
   15787                     Slog.i(
   15788                         TAG, "Exiting empty application process "
   15789                         + app.processName + " ("
   15790                         + (app.thread != null ? app.thread.asBinder() : null)
   15791                         + ")\n");
   15792                     if (app.pid > 0 && app.pid != MY_PID) {
   15793                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   15794                                 app.processName, app.setAdj, "empty");
   15795                         app.killedByAm = true;
   15796                         Process.killProcessQuiet(app.pid);
   15797                     } else {
   15798                         try {
   15799                             app.thread.scheduleExit();
   15800                         } catch (Exception e) {
   15801                             // Ignore exceptions.
   15802                         }
   15803                     }
   15804                     cleanUpApplicationRecordLocked(app, false, true, -1);
   15805                     mRemovedProcesses.remove(i);
   15806 
   15807                     if (app.persistent) {
   15808                         if (app.persistent) {
   15809                             addAppLocked(app.info, false);
   15810                         }
   15811                     }
   15812                 }
   15813             }
   15814 
   15815             // Now update the oom adj for all processes.
   15816             updateOomAdjLocked();
   15817         }
   15818     }
   15819 
   15820     /** This method sends the specified signal to each of the persistent apps */
   15821     public void signalPersistentProcesses(int sig) throws RemoteException {
   15822         if (sig != Process.SIGNAL_USR1) {
   15823             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   15824         }
   15825 
   15826         synchronized (this) {
   15827             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   15828                     != PackageManager.PERMISSION_GRANTED) {
   15829                 throw new SecurityException("Requires permission "
   15830                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   15831             }
   15832 
   15833             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15834                 ProcessRecord r = mLruProcesses.get(i);
   15835                 if (r.thread != null && r.persistent) {
   15836                     Process.sendSignal(r.pid, sig);
   15837                 }
   15838             }
   15839         }
   15840     }
   15841 
   15842     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   15843         if (proc == null || proc == mProfileProc) {
   15844             proc = mProfileProc;
   15845             path = mProfileFile;
   15846             profileType = mProfileType;
   15847             clearProfilerLocked();
   15848         }
   15849         if (proc == null) {
   15850             return;
   15851         }
   15852         try {
   15853             proc.thread.profilerControl(false, path, null, profileType);
   15854         } catch (RemoteException e) {
   15855             throw new IllegalStateException("Process disappeared");
   15856         }
   15857     }
   15858 
   15859     private void clearProfilerLocked() {
   15860         if (mProfileFd != null) {
   15861             try {
   15862                 mProfileFd.close();
   15863             } catch (IOException e) {
   15864             }
   15865         }
   15866         mProfileApp = null;
   15867         mProfileProc = null;
   15868         mProfileFile = null;
   15869         mProfileType = 0;
   15870         mAutoStopProfiler = false;
   15871     }
   15872 
   15873     public boolean profileControl(String process, int userId, boolean start,
   15874             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   15875 
   15876         try {
   15877             synchronized (this) {
   15878                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15879                 // its own permission.
   15880                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15881                         != PackageManager.PERMISSION_GRANTED) {
   15882                     throw new SecurityException("Requires permission "
   15883                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15884                 }
   15885 
   15886                 if (start && fd == null) {
   15887                     throw new IllegalArgumentException("null fd");
   15888                 }
   15889 
   15890                 ProcessRecord proc = null;
   15891                 if (process != null) {
   15892                     proc = findProcessLocked(process, userId, "profileControl");
   15893                 }
   15894 
   15895                 if (start && (proc == null || proc.thread == null)) {
   15896                     throw new IllegalArgumentException("Unknown process: " + process);
   15897                 }
   15898 
   15899                 if (start) {
   15900                     stopProfilerLocked(null, null, 0);
   15901                     setProfileApp(proc.info, proc.processName, path, fd, false);
   15902                     mProfileProc = proc;
   15903                     mProfileType = profileType;
   15904                     try {
   15905                         fd = fd.dup();
   15906                     } catch (IOException e) {
   15907                         fd = null;
   15908                     }
   15909                     proc.thread.profilerControl(start, path, fd, profileType);
   15910                     fd = null;
   15911                     mProfileFd = null;
   15912                 } else {
   15913                     stopProfilerLocked(proc, path, profileType);
   15914                     if (fd != null) {
   15915                         try {
   15916                             fd.close();
   15917                         } catch (IOException e) {
   15918                         }
   15919                     }
   15920                 }
   15921 
   15922                 return true;
   15923             }
   15924         } catch (RemoteException e) {
   15925             throw new IllegalStateException("Process disappeared");
   15926         } finally {
   15927             if (fd != null) {
   15928                 try {
   15929                     fd.close();
   15930                 } catch (IOException e) {
   15931                 }
   15932             }
   15933         }
   15934     }
   15935 
   15936     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   15937         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   15938                 userId, true, true, callName, null);
   15939         ProcessRecord proc = null;
   15940         try {
   15941             int pid = Integer.parseInt(process);
   15942             synchronized (mPidsSelfLocked) {
   15943                 proc = mPidsSelfLocked.get(pid);
   15944             }
   15945         } catch (NumberFormatException e) {
   15946         }
   15947 
   15948         if (proc == null) {
   15949             ArrayMap<String, SparseArray<ProcessRecord>> all
   15950                     = mProcessNames.getMap();
   15951             SparseArray<ProcessRecord> procs = all.get(process);
   15952             if (procs != null && procs.size() > 0) {
   15953                 proc = procs.valueAt(0);
   15954                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   15955                     for (int i=1; i<procs.size(); i++) {
   15956                         ProcessRecord thisProc = procs.valueAt(i);
   15957                         if (thisProc.userId == userId) {
   15958                             proc = thisProc;
   15959                             break;
   15960                         }
   15961                     }
   15962                 }
   15963             }
   15964         }
   15965 
   15966         return proc;
   15967     }
   15968 
   15969     public boolean dumpHeap(String process, int userId, boolean managed,
   15970             String path, ParcelFileDescriptor fd) throws RemoteException {
   15971 
   15972         try {
   15973             synchronized (this) {
   15974                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15975                 // its own permission (same as profileControl).
   15976                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15977                         != PackageManager.PERMISSION_GRANTED) {
   15978                     throw new SecurityException("Requires permission "
   15979                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15980                 }
   15981 
   15982                 if (fd == null) {
   15983                     throw new IllegalArgumentException("null fd");
   15984                 }
   15985 
   15986                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   15987                 if (proc == null || proc.thread == null) {
   15988                     throw new IllegalArgumentException("Unknown process: " + process);
   15989                 }
   15990 
   15991                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   15992                 if (!isDebuggable) {
   15993                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   15994                         throw new SecurityException("Process not debuggable: " + proc);
   15995                     }
   15996                 }
   15997 
   15998                 proc.thread.dumpHeap(managed, path, fd);
   15999                 fd = null;
   16000                 return true;
   16001             }
   16002         } catch (RemoteException e) {
   16003             throw new IllegalStateException("Process disappeared");
   16004         } finally {
   16005             if (fd != null) {
   16006                 try {
   16007                     fd.close();
   16008                 } catch (IOException e) {
   16009                 }
   16010             }
   16011         }
   16012     }
   16013 
   16014     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   16015     public void monitor() {
   16016         synchronized (this) { }
   16017     }
   16018 
   16019     void onCoreSettingsChange(Bundle settings) {
   16020         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   16021             ProcessRecord processRecord = mLruProcesses.get(i);
   16022             try {
   16023                 if (processRecord.thread != null) {
   16024                     processRecord.thread.setCoreSettings(settings);
   16025                 }
   16026             } catch (RemoteException re) {
   16027                 /* ignore */
   16028             }
   16029         }
   16030     }
   16031 
   16032     // Multi-user methods
   16033 
   16034     @Override
   16035     public boolean switchUser(final int userId) {
   16036         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16037                 != PackageManager.PERMISSION_GRANTED) {
   16038             String msg = "Permission Denial: switchUser() from pid="
   16039                     + Binder.getCallingPid()
   16040                     + ", uid=" + Binder.getCallingUid()
   16041                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16042             Slog.w(TAG, msg);
   16043             throw new SecurityException(msg);
   16044         }
   16045 
   16046         final long ident = Binder.clearCallingIdentity();
   16047         try {
   16048             synchronized (this) {
   16049                 final int oldUserId = mCurrentUserId;
   16050                 if (oldUserId == userId) {
   16051                     return true;
   16052                 }
   16053 
   16054                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   16055                 if (userInfo == null) {
   16056                     Slog.w(TAG, "No user info for user #" + userId);
   16057                     return false;
   16058                 }
   16059 
   16060                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   16061                         R.anim.screen_user_enter);
   16062 
   16063                 boolean needStart = false;
   16064 
   16065                 // If the user we are switching to is not currently started, then
   16066                 // we need to start it now.
   16067                 if (mStartedUsers.get(userId) == null) {
   16068                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   16069                     updateStartedUserArrayLocked();
   16070                     needStart = true;
   16071                 }
   16072 
   16073                 mCurrentUserId = userId;
   16074                 final Integer userIdInt = Integer.valueOf(userId);
   16075                 mUserLru.remove(userIdInt);
   16076                 mUserLru.add(userIdInt);
   16077 
   16078                 mWindowManager.setCurrentUser(userId);
   16079 
   16080                 // Once the internal notion of the active user has switched, we lock the device
   16081                 // with the option to show the user switcher on the keyguard.
   16082                 mWindowManager.lockNow(null);
   16083 
   16084                 final UserStartedState uss = mStartedUsers.get(userId);
   16085 
   16086                 // Make sure user is in the started state.  If it is currently
   16087                 // stopping, we need to knock that off.
   16088                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   16089                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   16090                     // so we can just fairly silently bring the user back from
   16091                     // the almost-dead.
   16092                     uss.mState = UserStartedState.STATE_RUNNING;
   16093                     updateStartedUserArrayLocked();
   16094                     needStart = true;
   16095                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   16096                     // This means ACTION_SHUTDOWN has been sent, so we will
   16097                     // need to treat this as a new boot of the user.
   16098                     uss.mState = UserStartedState.STATE_BOOTING;
   16099                     updateStartedUserArrayLocked();
   16100                     needStart = true;
   16101                 }
   16102 
   16103                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   16104                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   16105                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   16106                         oldUserId, userId, uss));
   16107                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   16108                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   16109                 if (needStart) {
   16110                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   16111                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16112                             | Intent.FLAG_RECEIVER_FOREGROUND);
   16113                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16114                     broadcastIntentLocked(null, null, intent,
   16115                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16116                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   16117                 }
   16118 
   16119                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   16120                     if (userId != 0) {
   16121                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   16122                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   16123                         broadcastIntentLocked(null, null, intent, null,
   16124                                 new IIntentReceiver.Stub() {
   16125                                     public void performReceive(Intent intent, int resultCode,
   16126                                             String data, Bundle extras, boolean ordered,
   16127                                             boolean sticky, int sendingUser) {
   16128                                         userInitialized(uss, userId);
   16129                                     }
   16130                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   16131                                 true, false, MY_PID, Process.SYSTEM_UID,
   16132                                 userId);
   16133                         uss.initializing = true;
   16134                     } else {
   16135                         getUserManagerLocked().makeInitialized(userInfo.id);
   16136                     }
   16137                 }
   16138 
   16139                 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
   16140                 if (homeInFront) {
   16141                     startHomeActivityLocked(userId);
   16142                 } else {
   16143                     mStackSupervisor.resumeTopActivitiesLocked();
   16144                 }
   16145 
   16146                 EventLogTags.writeAmSwitchUser(userId);
   16147                 getUserManagerLocked().userForeground(userId);
   16148                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
   16149                 if (needStart) {
   16150                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   16151                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16152                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16153                     broadcastIntentLocked(null, null, intent,
   16154                             null, new IIntentReceiver.Stub() {
   16155                                 @Override
   16156                                 public void performReceive(Intent intent, int resultCode, String data,
   16157                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   16158                                         throws RemoteException {
   16159                                 }
   16160                             }, 0, null, null,
   16161                             android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   16162                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16163                 }
   16164             }
   16165         } finally {
   16166             Binder.restoreCallingIdentity(ident);
   16167         }
   16168 
   16169         return true;
   16170     }
   16171 
   16172     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   16173         long ident = Binder.clearCallingIdentity();
   16174         try {
   16175             Intent intent;
   16176             if (oldUserId >= 0) {
   16177                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   16178                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16179                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16180                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
   16181                 broadcastIntentLocked(null, null, intent,
   16182                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16183                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
   16184             }
   16185             if (newUserId >= 0) {
   16186                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   16187                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16188                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16189                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   16190                 broadcastIntentLocked(null, null, intent,
   16191                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16192                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
   16193                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   16194                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16195                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16196                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   16197                 broadcastIntentLocked(null, null, intent,
   16198                         null, null, 0, null, null,
   16199                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   16200                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16201             }
   16202         } finally {
   16203             Binder.restoreCallingIdentity(ident);
   16204         }
   16205     }
   16206 
   16207     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   16208             final int newUserId) {
   16209         final int N = mUserSwitchObservers.beginBroadcast();
   16210         if (N > 0) {
   16211             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   16212                 int mCount = 0;
   16213                 @Override
   16214                 public void sendResult(Bundle data) throws RemoteException {
   16215                     synchronized (ActivityManagerService.this) {
   16216                         if (mCurUserSwitchCallback == this) {
   16217                             mCount++;
   16218                             if (mCount == N) {
   16219                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16220                             }
   16221                         }
   16222                     }
   16223                 }
   16224             };
   16225             synchronized (this) {
   16226                 uss.switching = true;
   16227                 mCurUserSwitchCallback = callback;
   16228             }
   16229             for (int i=0; i<N; i++) {
   16230                 try {
   16231                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   16232                             newUserId, callback);
   16233                 } catch (RemoteException e) {
   16234                 }
   16235             }
   16236         } else {
   16237             synchronized (this) {
   16238                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16239             }
   16240         }
   16241         mUserSwitchObservers.finishBroadcast();
   16242     }
   16243 
   16244     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16245         synchronized (this) {
   16246             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   16247             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16248         }
   16249     }
   16250 
   16251     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   16252         mCurUserSwitchCallback = null;
   16253         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   16254         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   16255                 oldUserId, newUserId, uss));
   16256     }
   16257 
   16258     void userInitialized(UserStartedState uss, int newUserId) {
   16259         completeSwitchAndInitalize(uss, newUserId, true, false);
   16260     }
   16261 
   16262     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16263         completeSwitchAndInitalize(uss, newUserId, false, true);
   16264     }
   16265 
   16266     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   16267             boolean clearInitializing, boolean clearSwitching) {
   16268         boolean unfrozen = false;
   16269         synchronized (this) {
   16270             if (clearInitializing) {
   16271                 uss.initializing = false;
   16272                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   16273             }
   16274             if (clearSwitching) {
   16275                 uss.switching = false;
   16276             }
   16277             if (!uss.switching && !uss.initializing) {
   16278                 mWindowManager.stopFreezingScreen();
   16279                 unfrozen = true;
   16280             }
   16281         }
   16282         if (unfrozen) {
   16283             final int N = mUserSwitchObservers.beginBroadcast();
   16284             for (int i=0; i<N; i++) {
   16285                 try {
   16286                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   16287                 } catch (RemoteException e) {
   16288                 }
   16289             }
   16290             mUserSwitchObservers.finishBroadcast();
   16291         }
   16292     }
   16293 
   16294     void finishUserSwitch(UserStartedState uss) {
   16295         synchronized (this) {
   16296             if (uss.mState == UserStartedState.STATE_BOOTING
   16297                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   16298                 uss.mState = UserStartedState.STATE_RUNNING;
   16299                 final int userId = uss.mHandle.getIdentifier();
   16300                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   16301                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16302                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   16303                 broadcastIntentLocked(null, null, intent,
   16304                         null, null, 0, null, null,
   16305                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   16306                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   16307             }
   16308             int num = mUserLru.size();
   16309             int i = 0;
   16310             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   16311                 Integer oldUserId = mUserLru.get(i);
   16312                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   16313                 if (oldUss == null) {
   16314                     // Shouldn't happen, but be sane if it does.
   16315                     mUserLru.remove(i);
   16316                     num--;
   16317                     continue;
   16318                 }
   16319                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   16320                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   16321                     // This user is already stopping, doesn't count.
   16322                     num--;
   16323                     i++;
   16324                     continue;
   16325                 }
   16326                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   16327                     // Owner and current can't be stopped, but count as running.
   16328                     i++;
   16329                     continue;
   16330                 }
   16331                 // This is a user to be stopped.
   16332                 stopUserLocked(oldUserId, null);
   16333                 num--;
   16334                 i++;
   16335             }
   16336         }
   16337     }
   16338 
   16339     @Override
   16340     public int stopUser(final int userId, final IStopUserCallback callback) {
   16341         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16342                 != PackageManager.PERMISSION_GRANTED) {
   16343             String msg = "Permission Denial: switchUser() from pid="
   16344                     + Binder.getCallingPid()
   16345                     + ", uid=" + Binder.getCallingUid()
   16346                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16347             Slog.w(TAG, msg);
   16348             throw new SecurityException(msg);
   16349         }
   16350         if (userId <= 0) {
   16351             throw new IllegalArgumentException("Can't stop primary user " + userId);
   16352         }
   16353         synchronized (this) {
   16354             return stopUserLocked(userId, callback);
   16355         }
   16356     }
   16357 
   16358     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   16359         if (mCurrentUserId == userId) {
   16360             return ActivityManager.USER_OP_IS_CURRENT;
   16361         }
   16362 
   16363         final UserStartedState uss = mStartedUsers.get(userId);
   16364         if (uss == null) {
   16365             // User is not started, nothing to do...  but we do need to
   16366             // callback if requested.
   16367             if (callback != null) {
   16368                 mHandler.post(new Runnable() {
   16369                     @Override
   16370                     public void run() {
   16371                         try {
   16372                             callback.userStopped(userId);
   16373                         } catch (RemoteException e) {
   16374                         }
   16375                     }
   16376                 });
   16377             }
   16378             return ActivityManager.USER_OP_SUCCESS;
   16379         }
   16380 
   16381         if (callback != null) {
   16382             uss.mStopCallbacks.add(callback);
   16383         }
   16384 
   16385         if (uss.mState != UserStartedState.STATE_STOPPING
   16386                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16387             uss.mState = UserStartedState.STATE_STOPPING;
   16388             updateStartedUserArrayLocked();
   16389 
   16390             long ident = Binder.clearCallingIdentity();
   16391             try {
   16392                 // We are going to broadcast ACTION_USER_STOPPING and then
   16393                 // once that is done send a final ACTION_SHUTDOWN and then
   16394                 // stop the user.
   16395                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   16396                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16397                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16398                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   16399                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   16400                 // This is the result receiver for the final shutdown broadcast.
   16401                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   16402                     @Override
   16403                     public void performReceive(Intent intent, int resultCode, String data,
   16404                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   16405                         finishUserStop(uss);
   16406                     }
   16407                 };
   16408                 // This is the result receiver for the initial stopping broadcast.
   16409                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
   16410                     @Override
   16411                     public void performReceive(Intent intent, int resultCode, String data,
   16412                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   16413                         // On to the next.
   16414                         synchronized (ActivityManagerService.this) {
   16415                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   16416                                 // Whoops, we are being started back up.  Abort, abort!
   16417                                 return;
   16418                             }
   16419                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   16420                         }
   16421                         broadcastIntentLocked(null, null, shutdownIntent,
   16422                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   16423                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   16424                     }
   16425                 };
   16426                 // Kick things off.
   16427                 broadcastIntentLocked(null, null, stoppingIntent,
   16428                         null, stoppingReceiver, 0, null, null,
   16429                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   16430                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16431             } finally {
   16432                 Binder.restoreCallingIdentity(ident);
   16433             }
   16434         }
   16435 
   16436         return ActivityManager.USER_OP_SUCCESS;
   16437     }
   16438 
   16439     void finishUserStop(UserStartedState uss) {
   16440         final int userId = uss.mHandle.getIdentifier();
   16441         boolean stopped;
   16442         ArrayList<IStopUserCallback> callbacks;
   16443         synchronized (this) {
   16444             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   16445             if (mStartedUsers.get(userId) != uss) {
   16446                 stopped = false;
   16447             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16448                 stopped = false;
   16449             } else {
   16450                 stopped = true;
   16451                 // User can no longer run.
   16452                 mStartedUsers.remove(userId);
   16453                 mUserLru.remove(Integer.valueOf(userId));
   16454                 updateStartedUserArrayLocked();
   16455 
   16456                 // Clean up all state and processes associated with the user.
   16457                 // Kill all the processes for the user.
   16458                 forceStopUserLocked(userId, "finish user");
   16459             }
   16460         }
   16461 
   16462         for (int i=0; i<callbacks.size(); i++) {
   16463             try {
   16464                 if (stopped) callbacks.get(i).userStopped(userId);
   16465                 else callbacks.get(i).userStopAborted(userId);
   16466             } catch (RemoteException e) {
   16467             }
   16468         }
   16469 
   16470         mStackSupervisor.removeUserLocked(userId);
   16471     }
   16472 
   16473     @Override
   16474     public UserInfo getCurrentUser() {
   16475         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16476                 != PackageManager.PERMISSION_GRANTED) && (
   16477                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16478                 != PackageManager.PERMISSION_GRANTED)) {
   16479             String msg = "Permission Denial: getCurrentUser() from pid="
   16480                     + Binder.getCallingPid()
   16481                     + ", uid=" + Binder.getCallingUid()
   16482                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16483             Slog.w(TAG, msg);
   16484             throw new SecurityException(msg);
   16485         }
   16486         synchronized (this) {
   16487             return getUserManagerLocked().getUserInfo(mCurrentUserId);
   16488         }
   16489     }
   16490 
   16491     int getCurrentUserIdLocked() {
   16492         return mCurrentUserId;
   16493     }
   16494 
   16495     @Override
   16496     public boolean isUserRunning(int userId, boolean orStopped) {
   16497         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16498                 != PackageManager.PERMISSION_GRANTED) {
   16499             String msg = "Permission Denial: isUserRunning() from pid="
   16500                     + Binder.getCallingPid()
   16501                     + ", uid=" + Binder.getCallingUid()
   16502                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16503             Slog.w(TAG, msg);
   16504             throw new SecurityException(msg);
   16505         }
   16506         synchronized (this) {
   16507             return isUserRunningLocked(userId, orStopped);
   16508         }
   16509     }
   16510 
   16511     boolean isUserRunningLocked(int userId, boolean orStopped) {
   16512         UserStartedState state = mStartedUsers.get(userId);
   16513         if (state == null) {
   16514             return false;
   16515         }
   16516         if (orStopped) {
   16517             return true;
   16518         }
   16519         return state.mState != UserStartedState.STATE_STOPPING
   16520                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   16521     }
   16522 
   16523     @Override
   16524     public int[] getRunningUserIds() {
   16525         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16526                 != PackageManager.PERMISSION_GRANTED) {
   16527             String msg = "Permission Denial: isUserRunning() from pid="
   16528                     + Binder.getCallingPid()
   16529                     + ", uid=" + Binder.getCallingUid()
   16530                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16531             Slog.w(TAG, msg);
   16532             throw new SecurityException(msg);
   16533         }
   16534         synchronized (this) {
   16535             return mStartedUserArray;
   16536         }
   16537     }
   16538 
   16539     private void updateStartedUserArrayLocked() {
   16540         int num = 0;
   16541         for (int i=0; i<mStartedUsers.size();  i++) {
   16542             UserStartedState uss = mStartedUsers.valueAt(i);
   16543             // This list does not include stopping users.
   16544             if (uss.mState != UserStartedState.STATE_STOPPING
   16545                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16546                 num++;
   16547             }
   16548         }
   16549         mStartedUserArray = new int[num];
   16550         num = 0;
   16551         for (int i=0; i<mStartedUsers.size();  i++) {
   16552             UserStartedState uss = mStartedUsers.valueAt(i);
   16553             if (uss.mState != UserStartedState.STATE_STOPPING
   16554                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16555                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   16556                 num++;
   16557             }
   16558         }
   16559     }
   16560 
   16561     @Override
   16562     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   16563         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16564                 != PackageManager.PERMISSION_GRANTED) {
   16565             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   16566                     + Binder.getCallingPid()
   16567                     + ", uid=" + Binder.getCallingUid()
   16568                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16569             Slog.w(TAG, msg);
   16570             throw new SecurityException(msg);
   16571         }
   16572 
   16573         mUserSwitchObservers.register(observer);
   16574     }
   16575 
   16576     @Override
   16577     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   16578         mUserSwitchObservers.unregister(observer);
   16579     }
   16580 
   16581     private boolean userExists(int userId) {
   16582         if (userId == 0) {
   16583             return true;
   16584         }
   16585         UserManagerService ums = getUserManagerLocked();
   16586         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   16587     }
   16588 
   16589     int[] getUsersLocked() {
   16590         UserManagerService ums = getUserManagerLocked();
   16591         return ums != null ? ums.getUserIds() : new int[] { 0 };
   16592     }
   16593 
   16594     UserManagerService getUserManagerLocked() {
   16595         if (mUserManager == null) {
   16596             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   16597             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   16598         }
   16599         return mUserManager;
   16600     }
   16601 
   16602     private int applyUserId(int uid, int userId) {
   16603         return UserHandle.getUid(userId, uid);
   16604     }
   16605 
   16606     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   16607         if (info == null) return null;
   16608         ApplicationInfo newInfo = new ApplicationInfo(info);
   16609         newInfo.uid = applyUserId(info.uid, userId);
   16610         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   16611                 + info.packageName;
   16612         return newInfo;
   16613     }
   16614 
   16615     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   16616         if (aInfo == null
   16617                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   16618             return aInfo;
   16619         }
   16620 
   16621         ActivityInfo info = new ActivityInfo(aInfo);
   16622         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   16623         return info;
   16624     }
   16625 }
   16626