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                             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, 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, 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, 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) {
   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, 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                             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                             ris.remove(i);
   9229                             i--;
   9230                         }
   9231                     }
   9232 
   9233                     final int[] users = getUsersLocked();
   9234                     for (int i=0; i<ris.size(); i++) {
   9235                         ActivityInfo ai = ris.get(i).activityInfo;
   9236                         ComponentName comp = new ComponentName(ai.packageName, ai.name);
   9237                         doneReceivers.add(comp);
   9238                         intent.setComponent(comp);
   9239                         for (int j=0; j<users.length; j++) {
   9240                             IIntentReceiver finisher = null;
   9241                             if (i == ris.size()-1 && j == users.length-1) {
   9242                                 finisher = new IIntentReceiver.Stub() {
   9243                                     public void performReceive(Intent intent, int resultCode,
   9244                                             String data, Bundle extras, boolean ordered,
   9245                                             boolean sticky, int sendingUser) {
   9246                                         // The raw IIntentReceiver interface is called
   9247                                         // with the AM lock held, so redispatch to
   9248                                         // execute our code without the lock.
   9249                                         mHandler.post(new Runnable() {
   9250                                             public void run() {
   9251                                                 synchronized (ActivityManagerService.this) {
   9252                                                     mDidUpdate = true;
   9253                                                 }
   9254                                                 writeLastDonePreBootReceivers(doneReceivers);
   9255                                                 showBootMessage(mContext.getText(
   9256                                                         R.string.android_upgrading_complete),
   9257                                                         false);
   9258                                                 systemReady(goingCallback);
   9259                                             }
   9260                                         });
   9261                                     }
   9262                                 };
   9263                             }
   9264                             Slog.i(TAG, "Sending system update to " + intent.getComponent()
   9265                                     + " for user " + users[j]);
   9266                             broadcastIntentLocked(null, null, intent, null, finisher,
   9267                                     0, null, null, null, AppOpsManager.OP_NONE,
   9268                                     true, false, MY_PID, Process.SYSTEM_UID,
   9269                                     users[j]);
   9270                             if (finisher != null) {
   9271                                 mWaitingUpdate = true;
   9272                             }
   9273                         }
   9274                     }
   9275                 }
   9276                 if (mWaitingUpdate) {
   9277                     return;
   9278                 }
   9279                 mDidUpdate = true;
   9280             }
   9281 
   9282             mAppOpsService.systemReady();
   9283             mSystemReady = true;
   9284             if (!mStartRunning) {
   9285                 return;
   9286             }
   9287         }
   9288 
   9289         ArrayList<ProcessRecord> procsToKill = null;
   9290         synchronized(mPidsSelfLocked) {
   9291             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
   9292                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
   9293                 if (!isAllowedWhileBooting(proc.info)){
   9294                     if (procsToKill == null) {
   9295                         procsToKill = new ArrayList<ProcessRecord>();
   9296                     }
   9297                     procsToKill.add(proc);
   9298                 }
   9299             }
   9300         }
   9301 
   9302         synchronized(this) {
   9303             if (procsToKill != null) {
   9304                 for (int i=procsToKill.size()-1; i>=0; i--) {
   9305                     ProcessRecord proc = procsToKill.get(i);
   9306                     Slog.i(TAG, "Removing system update proc: " + proc);
   9307                     removeProcessLocked(proc, true, false, "system update done");
   9308                 }
   9309             }
   9310 
   9311             // Now that we have cleaned up any update processes, we
   9312             // are ready to start launching real processes and know that
   9313             // we won't trample on them any more.
   9314             mProcessesReady = true;
   9315         }
   9316 
   9317         Slog.i(TAG, "System now ready");
   9318         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
   9319             SystemClock.uptimeMillis());
   9320 
   9321         synchronized(this) {
   9322             // Make sure we have no pre-ready processes sitting around.
   9323 
   9324             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9325                 ResolveInfo ri = mContext.getPackageManager()
   9326                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
   9327                                 STOCK_PM_FLAGS);
   9328                 CharSequence errorMsg = null;
   9329                 if (ri != null) {
   9330                     ActivityInfo ai = ri.activityInfo;
   9331                     ApplicationInfo app = ai.applicationInfo;
   9332                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   9333                         mTopAction = Intent.ACTION_FACTORY_TEST;
   9334                         mTopData = null;
   9335                         mTopComponent = new ComponentName(app.packageName,
   9336                                 ai.name);
   9337                     } else {
   9338                         errorMsg = mContext.getResources().getText(
   9339                                 com.android.internal.R.string.factorytest_not_system);
   9340                     }
   9341                 } else {
   9342                     errorMsg = mContext.getResources().getText(
   9343                             com.android.internal.R.string.factorytest_no_action);
   9344                 }
   9345                 if (errorMsg != null) {
   9346                     mTopAction = null;
   9347                     mTopData = null;
   9348                     mTopComponent = null;
   9349                     Message msg = Message.obtain();
   9350                     msg.what = SHOW_FACTORY_ERROR_MSG;
   9351                     msg.getData().putCharSequence("msg", errorMsg);
   9352                     mHandler.sendMessage(msg);
   9353                 }
   9354             }
   9355         }
   9356 
   9357         retrieveSettings();
   9358 
   9359         synchronized (this) {
   9360             readGrantedUriPermissionsLocked();
   9361         }
   9362 
   9363         if (goingCallback != null) goingCallback.run();
   9364 
   9365         synchronized (this) {
   9366             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
   9367                 try {
   9368                     List apps = AppGlobals.getPackageManager().
   9369                         getPersistentApplications(STOCK_PM_FLAGS);
   9370                     if (apps != null) {
   9371                         int N = apps.size();
   9372                         int i;
   9373                         for (i=0; i<N; i++) {
   9374                             ApplicationInfo info
   9375                                 = (ApplicationInfo)apps.get(i);
   9376                             if (info != null &&
   9377                                     !info.packageName.equals("android")) {
   9378                                 addAppLocked(info, false);
   9379                             }
   9380                         }
   9381                     }
   9382                 } catch (RemoteException ex) {
   9383                     // pm is in same process, this will never happen.
   9384                 }
   9385             }
   9386 
   9387             // Start up initial activity.
   9388             mBooting = true;
   9389 
   9390             try {
   9391                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
   9392                     Message msg = Message.obtain();
   9393                     msg.what = SHOW_UID_ERROR_MSG;
   9394                     mHandler.sendMessage(msg);
   9395                 }
   9396             } catch (RemoteException e) {
   9397             }
   9398 
   9399             long ident = Binder.clearCallingIdentity();
   9400             try {
   9401                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   9402                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   9403                         | Intent.FLAG_RECEIVER_FOREGROUND);
   9404                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9405                 broadcastIntentLocked(null, null, intent,
   9406                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   9407                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
   9408                 intent = new Intent(Intent.ACTION_USER_STARTING);
   9409                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   9410                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
   9411                 broadcastIntentLocked(null, null, intent,
   9412                         null, new IIntentReceiver.Stub() {
   9413                             @Override
   9414                             public void performReceive(Intent intent, int resultCode, String data,
   9415                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   9416                                     throws RemoteException {
   9417                             }
   9418                         }, 0, null, null,
   9419                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   9420                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   9421             } finally {
   9422                 Binder.restoreCallingIdentity(ident);
   9423             }
   9424             mStackSupervisor.resumeTopActivitiesLocked();
   9425             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
   9426         }
   9427     }
   9428 
   9429     private boolean makeAppCrashingLocked(ProcessRecord app,
   9430             String shortMsg, String longMsg, String stackTrace) {
   9431         app.crashing = true;
   9432         app.crashingReport = generateProcessError(app,
   9433                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
   9434         startAppProblemLocked(app);
   9435         app.stopFreezingAllLocked();
   9436         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
   9437     }
   9438 
   9439     private void makeAppNotRespondingLocked(ProcessRecord app,
   9440             String activity, String shortMsg, String longMsg) {
   9441         app.notResponding = true;
   9442         app.notRespondingReport = generateProcessError(app,
   9443                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
   9444                 activity, shortMsg, longMsg, null);
   9445         startAppProblemLocked(app);
   9446         app.stopFreezingAllLocked();
   9447     }
   9448 
   9449     /**
   9450      * Generate a process error record, suitable for attachment to a ProcessRecord.
   9451      *
   9452      * @param app The ProcessRecord in which the error occurred.
   9453      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
   9454      *                      ActivityManager.AppErrorStateInfo
   9455      * @param activity The activity associated with the crash, if known.
   9456      * @param shortMsg Short message describing the crash.
   9457      * @param longMsg Long message describing the crash.
   9458      * @param stackTrace Full crash stack trace, may be null.
   9459      *
   9460      * @return Returns a fully-formed AppErrorStateInfo record.
   9461      */
   9462     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
   9463             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
   9464         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
   9465 
   9466         report.condition = condition;
   9467         report.processName = app.processName;
   9468         report.pid = app.pid;
   9469         report.uid = app.info.uid;
   9470         report.tag = activity;
   9471         report.shortMsg = shortMsg;
   9472         report.longMsg = longMsg;
   9473         report.stackTrace = stackTrace;
   9474 
   9475         return report;
   9476     }
   9477 
   9478     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
   9479         synchronized (this) {
   9480             app.crashing = false;
   9481             app.crashingReport = null;
   9482             app.notResponding = false;
   9483             app.notRespondingReport = null;
   9484             if (app.anrDialog == fromDialog) {
   9485                 app.anrDialog = null;
   9486             }
   9487             if (app.waitDialog == fromDialog) {
   9488                 app.waitDialog = null;
   9489             }
   9490             if (app.pid > 0 && app.pid != MY_PID) {
   9491                 handleAppCrashLocked(app, null, null, null);
   9492                 killUnneededProcessLocked(app, "user request after error");
   9493             }
   9494         }
   9495     }
   9496 
   9497     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
   9498             String stackTrace) {
   9499         if (mHeadless) {
   9500             Log.e(TAG, "handleAppCrashLocked: " + app.processName);
   9501             return false;
   9502         }
   9503         long now = SystemClock.uptimeMillis();
   9504 
   9505         Long crashTime;
   9506         if (!app.isolated) {
   9507             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
   9508         } else {
   9509             crashTime = null;
   9510         }
   9511         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
   9512             // This process loses!
   9513             Slog.w(TAG, "Process " + app.info.processName
   9514                     + " has crashed too many times: killing!");
   9515             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
   9516                     app.userId, app.info.processName, app.uid);
   9517             mStackSupervisor.handleAppCrashLocked(app);
   9518             if (!app.persistent) {
   9519                 // We don't want to start this process again until the user
   9520                 // explicitly does so...  but for persistent process, we really
   9521                 // need to keep it running.  If a persistent process is actually
   9522                 // repeatedly crashing, then badness for everyone.
   9523                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
   9524                         app.info.processName);
   9525                 if (!app.isolated) {
   9526                     // XXX We don't have a way to mark isolated processes
   9527                     // as bad, since they don't have a peristent identity.
   9528                     mBadProcesses.put(app.info.processName, app.uid,
   9529                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
   9530                     mProcessCrashTimes.remove(app.info.processName, app.uid);
   9531                 }
   9532                 app.bad = true;
   9533                 app.removed = true;
   9534                 // Don't let services in this process be restarted and potentially
   9535                 // annoy the user repeatedly.  Unless it is persistent, since those
   9536                 // processes run critical code.
   9537                 removeProcessLocked(app, false, false, "crash");
   9538                 mStackSupervisor.resumeTopActivitiesLocked();
   9539                 return false;
   9540             }
   9541             mStackSupervisor.resumeTopActivitiesLocked();
   9542         } else {
   9543             mStackSupervisor.finishTopRunningActivityLocked(app);
   9544         }
   9545 
   9546         // Bump up the crash count of any services currently running in the proc.
   9547         for (int i=app.services.size()-1; i>=0; i--) {
   9548             // Any services running in the application need to be placed
   9549             // back in the pending list.
   9550             ServiceRecord sr = app.services.valueAt(i);
   9551             sr.crashCount++;
   9552         }
   9553 
   9554         // If the crashing process is what we consider to be the "home process" and it has been
   9555         // replaced by a third-party app, clear the package preferred activities from packages
   9556         // with a home activity running in the process to prevent a repeatedly crashing app
   9557         // from blocking the user to manually clear the list.
   9558         final ArrayList<ActivityRecord> activities = app.activities;
   9559         if (app == mHomeProcess && activities.size() > 0
   9560                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   9561             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   9562                 final ActivityRecord r = activities.get(activityNdx);
   9563                 if (r.isHomeActivity()) {
   9564                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
   9565                     try {
   9566                         ActivityThread.getPackageManager()
   9567                                 .clearPackagePreferredActivities(r.packageName);
   9568                     } catch (RemoteException c) {
   9569                         // pm is in same process, this will never happen.
   9570                     }
   9571                 }
   9572             }
   9573         }
   9574 
   9575         if (!app.isolated) {
   9576             // XXX Can't keep track of crash times for isolated processes,
   9577             // because they don't have a perisistent identity.
   9578             mProcessCrashTimes.put(app.info.processName, app.uid, now);
   9579         }
   9580 
   9581         return true;
   9582     }
   9583 
   9584     void startAppProblemLocked(ProcessRecord app) {
   9585         if (app.userId == mCurrentUserId) {
   9586             app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
   9587                     mContext, app.info.packageName, app.info.flags);
   9588         } else {
   9589             // If this app is not running under the current user, then we
   9590             // can't give it a report button because that would require
   9591             // launching the report UI under a different user.
   9592             app.errorReportReceiver = null;
   9593         }
   9594         skipCurrentReceiverLocked(app);
   9595     }
   9596 
   9597     void skipCurrentReceiverLocked(ProcessRecord app) {
   9598         for (BroadcastQueue queue : mBroadcastQueues) {
   9599             queue.skipCurrentReceiverLocked(app);
   9600         }
   9601     }
   9602 
   9603     /**
   9604      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
   9605      * The application process will exit immediately after this call returns.
   9606      * @param app object of the crashing app, null for the system server
   9607      * @param crashInfo describing the exception
   9608      */
   9609     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
   9610         ProcessRecord r = findAppProcess(app, "Crash");
   9611         final String processName = app == null ? "system_server"
   9612                 : (r == null ? "unknown" : r.processName);
   9613 
   9614         handleApplicationCrashInner("crash", r, processName, crashInfo);
   9615     }
   9616 
   9617     /* Native crash reporting uses this inner version because it needs to be somewhat
   9618      * decoupled from the AM-managed cleanup lifecycle
   9619      */
   9620     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
   9621             ApplicationErrorReport.CrashInfo crashInfo) {
   9622         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
   9623                 UserHandle.getUserId(Binder.getCallingUid()), processName,
   9624                 r == null ? -1 : r.info.flags,
   9625                 crashInfo.exceptionClassName,
   9626                 crashInfo.exceptionMessage,
   9627                 crashInfo.throwFileName,
   9628                 crashInfo.throwLineNumber);
   9629 
   9630         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
   9631 
   9632         crashApplication(r, crashInfo);
   9633     }
   9634 
   9635     public void handleApplicationStrictModeViolation(
   9636             IBinder app,
   9637             int violationMask,
   9638             StrictMode.ViolationInfo info) {
   9639         ProcessRecord r = findAppProcess(app, "StrictMode");
   9640         if (r == null) {
   9641             return;
   9642         }
   9643 
   9644         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
   9645             Integer stackFingerprint = info.hashCode();
   9646             boolean logIt = true;
   9647             synchronized (mAlreadyLoggedViolatedStacks) {
   9648                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
   9649                     logIt = false;
   9650                     // TODO: sub-sample into EventLog for these, with
   9651                     // the info.durationMillis?  Then we'd get
   9652                     // the relative pain numbers, without logging all
   9653                     // the stack traces repeatedly.  We'd want to do
   9654                     // likewise in the client code, which also does
   9655                     // dup suppression, before the Binder call.
   9656                 } else {
   9657                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
   9658                         mAlreadyLoggedViolatedStacks.clear();
   9659                     }
   9660                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
   9661                 }
   9662             }
   9663             if (logIt) {
   9664                 logStrictModeViolationToDropBox(r, info);
   9665             }
   9666         }
   9667 
   9668         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
   9669             AppErrorResult result = new AppErrorResult();
   9670             synchronized (this) {
   9671                 final long origId = Binder.clearCallingIdentity();
   9672 
   9673                 Message msg = Message.obtain();
   9674                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
   9675                 HashMap<String, Object> data = new HashMap<String, Object>();
   9676                 data.put("result", result);
   9677                 data.put("app", r);
   9678                 data.put("violationMask", violationMask);
   9679                 data.put("info", info);
   9680                 msg.obj = data;
   9681                 mHandler.sendMessage(msg);
   9682 
   9683                 Binder.restoreCallingIdentity(origId);
   9684             }
   9685             int res = result.get();
   9686             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
   9687         }
   9688     }
   9689 
   9690     // Depending on the policy in effect, there could be a bunch of
   9691     // these in quick succession so we try to batch these together to
   9692     // minimize disk writes, number of dropbox entries, and maximize
   9693     // compression, by having more fewer, larger records.
   9694     private void logStrictModeViolationToDropBox(
   9695             ProcessRecord process,
   9696             StrictMode.ViolationInfo info) {
   9697         if (info == null) {
   9698             return;
   9699         }
   9700         final boolean isSystemApp = process == null ||
   9701                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
   9702                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
   9703         final String processName = process == null ? "unknown" : process.processName;
   9704         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
   9705         final DropBoxManager dbox = (DropBoxManager)
   9706                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9707 
   9708         // Exit early if the dropbox isn't configured to accept this report type.
   9709         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9710 
   9711         boolean bufferWasEmpty;
   9712         boolean needsFlush;
   9713         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
   9714         synchronized (sb) {
   9715             bufferWasEmpty = sb.length() == 0;
   9716             appendDropBoxProcessHeaders(process, processName, sb);
   9717             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9718             sb.append("System-App: ").append(isSystemApp).append("\n");
   9719             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
   9720             if (info.violationNumThisLoop != 0) {
   9721                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
   9722             }
   9723             if (info.numAnimationsRunning != 0) {
   9724                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
   9725             }
   9726             if (info.broadcastIntentAction != null) {
   9727                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
   9728             }
   9729             if (info.durationMillis != -1) {
   9730                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
   9731             }
   9732             if (info.numInstances != -1) {
   9733                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
   9734             }
   9735             if (info.tags != null) {
   9736                 for (String tag : info.tags) {
   9737                     sb.append("Span-Tag: ").append(tag).append("\n");
   9738                 }
   9739             }
   9740             sb.append("\n");
   9741             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
   9742                 sb.append(info.crashInfo.stackTrace);
   9743             }
   9744             sb.append("\n");
   9745 
   9746             // Only buffer up to ~64k.  Various logging bits truncate
   9747             // things at 128k.
   9748             needsFlush = (sb.length() > 64 * 1024);
   9749         }
   9750 
   9751         // Flush immediately if the buffer's grown too large, or this
   9752         // is a non-system app.  Non-system apps are isolated with a
   9753         // different tag & policy and not batched.
   9754         //
   9755         // Batching is useful during internal testing with
   9756         // StrictMode settings turned up high.  Without batching,
   9757         // thousands of separate files could be created on boot.
   9758         if (!isSystemApp || needsFlush) {
   9759             new Thread("Error dump: " + dropboxTag) {
   9760                 @Override
   9761                 public void run() {
   9762                     String report;
   9763                     synchronized (sb) {
   9764                         report = sb.toString();
   9765                         sb.delete(0, sb.length());
   9766                         sb.trimToSize();
   9767                     }
   9768                     if (report.length() != 0) {
   9769                         dbox.addText(dropboxTag, report);
   9770                     }
   9771                 }
   9772             }.start();
   9773             return;
   9774         }
   9775 
   9776         // System app batching:
   9777         if (!bufferWasEmpty) {
   9778             // An existing dropbox-writing thread is outstanding, so
   9779             // we don't need to start it up.  The existing thread will
   9780             // catch the buffer appends we just did.
   9781             return;
   9782         }
   9783 
   9784         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
   9785         // (After this point, we shouldn't access AMS internal data structures.)
   9786         new Thread("Error dump: " + dropboxTag) {
   9787             @Override
   9788             public void run() {
   9789                 // 5 second sleep to let stacks arrive and be batched together
   9790                 try {
   9791                     Thread.sleep(5000);  // 5 seconds
   9792                 } catch (InterruptedException e) {}
   9793 
   9794                 String errorReport;
   9795                 synchronized (mStrictModeBuffer) {
   9796                     errorReport = mStrictModeBuffer.toString();
   9797                     if (errorReport.length() == 0) {
   9798                         return;
   9799                     }
   9800                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
   9801                     mStrictModeBuffer.trimToSize();
   9802                 }
   9803                 dbox.addText(dropboxTag, errorReport);
   9804             }
   9805         }.start();
   9806     }
   9807 
   9808     /**
   9809      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
   9810      * @param app object of the crashing app, null for the system server
   9811      * @param tag reported by the caller
   9812      * @param crashInfo describing the context of the error
   9813      * @return true if the process should exit immediately (WTF is fatal)
   9814      */
   9815     public boolean handleApplicationWtf(IBinder app, String tag,
   9816             ApplicationErrorReport.CrashInfo crashInfo) {
   9817         ProcessRecord r = findAppProcess(app, "WTF");
   9818         final String processName = app == null ? "system_server"
   9819                 : (r == null ? "unknown" : r.processName);
   9820 
   9821         EventLog.writeEvent(EventLogTags.AM_WTF,
   9822                 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
   9823                 processName,
   9824                 r == null ? -1 : r.info.flags,
   9825                 tag, crashInfo.exceptionMessage);
   9826 
   9827         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
   9828 
   9829         if (r != null && r.pid != Process.myPid() &&
   9830                 Settings.Global.getInt(mContext.getContentResolver(),
   9831                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
   9832             crashApplication(r, crashInfo);
   9833             return true;
   9834         } else {
   9835             return false;
   9836         }
   9837     }
   9838 
   9839     /**
   9840      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
   9841      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
   9842      */
   9843     private ProcessRecord findAppProcess(IBinder app, String reason) {
   9844         if (app == null) {
   9845             return null;
   9846         }
   9847 
   9848         synchronized (this) {
   9849             final int NP = mProcessNames.getMap().size();
   9850             for (int ip=0; ip<NP; ip++) {
   9851                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
   9852                 final int NA = apps.size();
   9853                 for (int ia=0; ia<NA; ia++) {
   9854                     ProcessRecord p = apps.valueAt(ia);
   9855                     if (p.thread != null && p.thread.asBinder() == app) {
   9856                         return p;
   9857                     }
   9858                 }
   9859             }
   9860 
   9861             Slog.w(TAG, "Can't find mystery application for " + reason
   9862                     + " from pid=" + Binder.getCallingPid()
   9863                     + " uid=" + Binder.getCallingUid() + ": " + app);
   9864             return null;
   9865         }
   9866     }
   9867 
   9868     /**
   9869      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
   9870      * to append various headers to the dropbox log text.
   9871      */
   9872     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
   9873             StringBuilder sb) {
   9874         // Watchdog thread ends up invoking this function (with
   9875         // a null ProcessRecord) to add the stack file to dropbox.
   9876         // Do not acquire a lock on this (am) in such cases, as it
   9877         // could cause a potential deadlock, if and when watchdog
   9878         // is invoked due to unavailability of lock on am and it
   9879         // would prevent watchdog from killing system_server.
   9880         if (process == null) {
   9881             sb.append("Process: ").append(processName).append("\n");
   9882             return;
   9883         }
   9884         // Note: ProcessRecord 'process' is guarded by the service
   9885         // instance.  (notably process.pkgList, which could otherwise change
   9886         // concurrently during execution of this method)
   9887         synchronized (this) {
   9888             sb.append("Process: ").append(processName).append("\n");
   9889             int flags = process.info.flags;
   9890             IPackageManager pm = AppGlobals.getPackageManager();
   9891             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
   9892             for (int ip=0; ip<process.pkgList.size(); ip++) {
   9893                 String pkg = process.pkgList.keyAt(ip);
   9894                 sb.append("Package: ").append(pkg);
   9895                 try {
   9896                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
   9897                     if (pi != null) {
   9898                         sb.append(" v").append(pi.versionCode);
   9899                         if (pi.versionName != null) {
   9900                             sb.append(" (").append(pi.versionName).append(")");
   9901                         }
   9902                     }
   9903                 } catch (RemoteException e) {
   9904                     Slog.e(TAG, "Error getting package info: " + pkg, e);
   9905                 }
   9906                 sb.append("\n");
   9907             }
   9908         }
   9909     }
   9910 
   9911     private static String processClass(ProcessRecord process) {
   9912         if (process == null || process.pid == MY_PID) {
   9913             return "system_server";
   9914         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   9915             return "system_app";
   9916         } else {
   9917             return "data_app";
   9918         }
   9919     }
   9920 
   9921     /**
   9922      * Write a description of an error (crash, WTF, ANR) to the drop box.
   9923      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
   9924      * @param process which caused the error, null means the system server
   9925      * @param activity which triggered the error, null if unknown
   9926      * @param parent activity related to the error, null if unknown
   9927      * @param subject line related to the error, null if absent
   9928      * @param report in long form describing the error, null if absent
   9929      * @param logFile to include in the report, null if none
   9930      * @param crashInfo giving an application stack trace, null if absent
   9931      */
   9932     public void addErrorToDropBox(String eventType,
   9933             ProcessRecord process, String processName, ActivityRecord activity,
   9934             ActivityRecord parent, String subject,
   9935             final String report, final File logFile,
   9936             final ApplicationErrorReport.CrashInfo crashInfo) {
   9937         // NOTE -- this must never acquire the ActivityManagerService lock,
   9938         // otherwise the watchdog may be prevented from resetting the system.
   9939 
   9940         final String dropboxTag = processClass(process) + "_" + eventType;
   9941         final DropBoxManager dbox = (DropBoxManager)
   9942                 mContext.getSystemService(Context.DROPBOX_SERVICE);
   9943 
   9944         // Exit early if the dropbox isn't configured to accept this report type.
   9945         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
   9946 
   9947         final StringBuilder sb = new StringBuilder(1024);
   9948         appendDropBoxProcessHeaders(process, processName, sb);
   9949         if (activity != null) {
   9950             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
   9951         }
   9952         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
   9953             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
   9954         }
   9955         if (parent != null && parent != activity) {
   9956             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
   9957         }
   9958         if (subject != null) {
   9959             sb.append("Subject: ").append(subject).append("\n");
   9960         }
   9961         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
   9962         if (Debug.isDebuggerConnected()) {
   9963             sb.append("Debugger: Connected\n");
   9964         }
   9965         sb.append("\n");
   9966 
   9967         // Do the rest in a worker thread to avoid blocking the caller on I/O
   9968         // (After this point, we shouldn't access AMS internal data structures.)
   9969         Thread worker = new Thread("Error dump: " + dropboxTag) {
   9970             @Override
   9971             public void run() {
   9972                 if (report != null) {
   9973                     sb.append(report);
   9974                 }
   9975                 if (logFile != null) {
   9976                     try {
   9977                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
   9978                                     "\n\n[[TRUNCATED]]"));
   9979                     } catch (IOException e) {
   9980                         Slog.e(TAG, "Error reading " + logFile, e);
   9981                     }
   9982                 }
   9983                 if (crashInfo != null && crashInfo.stackTrace != null) {
   9984                     sb.append(crashInfo.stackTrace);
   9985                 }
   9986 
   9987                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
   9988                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
   9989                 if (lines > 0) {
   9990                     sb.append("\n");
   9991 
   9992                     // Merge several logcat streams, and take the last N lines
   9993                     InputStreamReader input = null;
   9994                     try {
   9995                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
   9996                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
   9997                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
   9998 
   9999                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
   10000                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
   10001                         input = new InputStreamReader(logcat.getInputStream());
   10002 
   10003                         int num;
   10004                         char[] buf = new char[8192];
   10005                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
   10006                     } catch (IOException e) {
   10007                         Slog.e(TAG, "Error running logcat", e);
   10008                     } finally {
   10009                         if (input != null) try { input.close(); } catch (IOException e) {}
   10010                     }
   10011                 }
   10012 
   10013                 dbox.addText(dropboxTag, sb.toString());
   10014             }
   10015         };
   10016 
   10017         if (process == null) {
   10018             // If process is null, we are being called from some internal code
   10019             // and may be about to die -- run this synchronously.
   10020             worker.run();
   10021         } else {
   10022             worker.start();
   10023         }
   10024     }
   10025 
   10026     /**
   10027      * Bring up the "unexpected error" dialog box for a crashing app.
   10028      * Deal with edge cases (intercepts from instrumented applications,
   10029      * ActivityController, error intent receivers, that sort of thing).
   10030      * @param r the application crashing
   10031      * @param crashInfo describing the failure
   10032      */
   10033     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
   10034         long timeMillis = System.currentTimeMillis();
   10035         String shortMsg = crashInfo.exceptionClassName;
   10036         String longMsg = crashInfo.exceptionMessage;
   10037         String stackTrace = crashInfo.stackTrace;
   10038         if (shortMsg != null && longMsg != null) {
   10039             longMsg = shortMsg + ": " + longMsg;
   10040         } else if (shortMsg != null) {
   10041             longMsg = shortMsg;
   10042         }
   10043 
   10044         AppErrorResult result = new AppErrorResult();
   10045         synchronized (this) {
   10046             if (mController != null) {
   10047                 try {
   10048                     String name = r != null ? r.processName : null;
   10049                     int pid = r != null ? r.pid : Binder.getCallingPid();
   10050                     if (!mController.appCrashed(name, pid,
   10051                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
   10052                         Slog.w(TAG, "Force-killing crashed app " + name
   10053                                 + " at watcher's request");
   10054                         Process.killProcess(pid);
   10055                         return;
   10056                     }
   10057                 } catch (RemoteException e) {
   10058                     mController = null;
   10059                     Watchdog.getInstance().setActivityController(null);
   10060                 }
   10061             }
   10062 
   10063             final long origId = Binder.clearCallingIdentity();
   10064 
   10065             // If this process is running instrumentation, finish it.
   10066             if (r != null && r.instrumentationClass != null) {
   10067                 Slog.w(TAG, "Error in app " + r.processName
   10068                       + " running instrumentation " + r.instrumentationClass + ":");
   10069                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
   10070                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
   10071                 Bundle info = new Bundle();
   10072                 info.putString("shortMsg", shortMsg);
   10073                 info.putString("longMsg", longMsg);
   10074                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
   10075                 Binder.restoreCallingIdentity(origId);
   10076                 return;
   10077             }
   10078 
   10079             // If we can't identify the process or it's already exceeded its crash quota,
   10080             // quit right away without showing a crash dialog.
   10081             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
   10082                 Binder.restoreCallingIdentity(origId);
   10083                 return;
   10084             }
   10085 
   10086             Message msg = Message.obtain();
   10087             msg.what = SHOW_ERROR_MSG;
   10088             HashMap data = new HashMap();
   10089             data.put("result", result);
   10090             data.put("app", r);
   10091             msg.obj = data;
   10092             mHandler.sendMessage(msg);
   10093 
   10094             Binder.restoreCallingIdentity(origId);
   10095         }
   10096 
   10097         int res = result.get();
   10098 
   10099         Intent appErrorIntent = null;
   10100         synchronized (this) {
   10101             if (r != null && !r.isolated) {
   10102                 // XXX Can't keep track of crash time for isolated processes,
   10103                 // since they don't have a persistent identity.
   10104                 mProcessCrashTimes.put(r.info.processName, r.uid,
   10105                         SystemClock.uptimeMillis());
   10106             }
   10107             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
   10108                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
   10109             }
   10110         }
   10111 
   10112         if (appErrorIntent != null) {
   10113             try {
   10114                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
   10115             } catch (ActivityNotFoundException e) {
   10116                 Slog.w(TAG, "bug report receiver dissappeared", e);
   10117             }
   10118         }
   10119     }
   10120 
   10121     Intent createAppErrorIntentLocked(ProcessRecord r,
   10122             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   10123         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
   10124         if (report == null) {
   10125             return null;
   10126         }
   10127         Intent result = new Intent(Intent.ACTION_APP_ERROR);
   10128         result.setComponent(r.errorReportReceiver);
   10129         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
   10130         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   10131         return result;
   10132     }
   10133 
   10134     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
   10135             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
   10136         if (r.errorReportReceiver == null) {
   10137             return null;
   10138         }
   10139 
   10140         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
   10141             return null;
   10142         }
   10143 
   10144         ApplicationErrorReport report = new ApplicationErrorReport();
   10145         report.packageName = r.info.packageName;
   10146         report.installerPackageName = r.errorReportReceiver.getPackageName();
   10147         report.processName = r.processName;
   10148         report.time = timeMillis;
   10149         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10150 
   10151         if (r.crashing || r.forceCrashReport) {
   10152             report.type = ApplicationErrorReport.TYPE_CRASH;
   10153             report.crashInfo = crashInfo;
   10154         } else if (r.notResponding) {
   10155             report.type = ApplicationErrorReport.TYPE_ANR;
   10156             report.anrInfo = new ApplicationErrorReport.AnrInfo();
   10157 
   10158             report.anrInfo.activity = r.notRespondingReport.tag;
   10159             report.anrInfo.cause = r.notRespondingReport.shortMsg;
   10160             report.anrInfo.info = r.notRespondingReport.longMsg;
   10161         }
   10162 
   10163         return report;
   10164     }
   10165 
   10166     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
   10167         enforceNotIsolatedCaller("getProcessesInErrorState");
   10168         // assume our apps are happy - lazy create the list
   10169         List<ActivityManager.ProcessErrorStateInfo> errList = null;
   10170 
   10171         final boolean allUsers = ActivityManager.checkUidPermission(
   10172                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10173                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10174         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10175 
   10176         synchronized (this) {
   10177 
   10178             // iterate across all processes
   10179             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10180                 ProcessRecord app = mLruProcesses.get(i);
   10181                 if (!allUsers && app.userId != userId) {
   10182                     continue;
   10183                 }
   10184                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
   10185                     // This one's in trouble, so we'll generate a report for it
   10186                     // crashes are higher priority (in case there's a crash *and* an anr)
   10187                     ActivityManager.ProcessErrorStateInfo report = null;
   10188                     if (app.crashing) {
   10189                         report = app.crashingReport;
   10190                     } else if (app.notResponding) {
   10191                         report = app.notRespondingReport;
   10192                     }
   10193 
   10194                     if (report != null) {
   10195                         if (errList == null) {
   10196                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
   10197                         }
   10198                         errList.add(report);
   10199                     } else {
   10200                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
   10201                                 " crashing = " + app.crashing +
   10202                                 " notResponding = " + app.notResponding);
   10203                     }
   10204                 }
   10205             }
   10206         }
   10207 
   10208         return errList;
   10209     }
   10210 
   10211     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
   10212         if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   10213             if (currApp != null) {
   10214                 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
   10215             }
   10216             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10217         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   10218             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10219         } else if (adj >= ProcessList.HOME_APP_ADJ) {
   10220             if (currApp != null) {
   10221                 currApp.lru = 0;
   10222             }
   10223             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   10224         } else if (adj >= ProcessList.SERVICE_ADJ) {
   10225             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   10226         } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   10227             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   10228         } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   10229             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   10230         } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   10231             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   10232         } else {
   10233             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   10234         }
   10235     }
   10236 
   10237     private void fillInProcMemInfo(ProcessRecord app,
   10238             ActivityManager.RunningAppProcessInfo outInfo) {
   10239         outInfo.pid = app.pid;
   10240         outInfo.uid = app.info.uid;
   10241         if (mHeavyWeightProcess == app) {
   10242             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
   10243         }
   10244         if (app.persistent) {
   10245             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
   10246         }
   10247         if (app.activities.size() > 0) {
   10248             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
   10249         }
   10250         outInfo.lastTrimLevel = app.trimMemoryLevel;
   10251         int adj = app.curAdj;
   10252         outInfo.importance = oomAdjToImportance(adj, outInfo);
   10253         outInfo.importanceReasonCode = app.adjTypeCode;
   10254     }
   10255 
   10256     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
   10257         enforceNotIsolatedCaller("getRunningAppProcesses");
   10258         // Lazy instantiation of list
   10259         List<ActivityManager.RunningAppProcessInfo> runList = null;
   10260         final boolean allUsers = ActivityManager.checkUidPermission(
   10261                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10262                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
   10263         int userId = UserHandle.getUserId(Binder.getCallingUid());
   10264         synchronized (this) {
   10265             // Iterate across all processes
   10266             for (int i=mLruProcesses.size()-1; i>=0; i--) {
   10267                 ProcessRecord app = mLruProcesses.get(i);
   10268                 if (!allUsers && app.userId != userId) {
   10269                     continue;
   10270                 }
   10271                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
   10272                     // Generate process state info for running application
   10273                     ActivityManager.RunningAppProcessInfo currApp =
   10274                         new ActivityManager.RunningAppProcessInfo(app.processName,
   10275                                 app.pid, app.getPackageList());
   10276                     fillInProcMemInfo(app, currApp);
   10277                     if (app.adjSource instanceof ProcessRecord) {
   10278                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
   10279                         currApp.importanceReasonImportance = oomAdjToImportance(
   10280                                 app.adjSourceOom, null);
   10281                     } else if (app.adjSource instanceof ActivityRecord) {
   10282                         ActivityRecord r = (ActivityRecord)app.adjSource;
   10283                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
   10284                     }
   10285                     if (app.adjTarget instanceof ComponentName) {
   10286                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
   10287                     }
   10288                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
   10289                     //        + " lru=" + currApp.lru);
   10290                     if (runList == null) {
   10291                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
   10292                     }
   10293                     runList.add(currApp);
   10294                 }
   10295             }
   10296         }
   10297         return runList;
   10298     }
   10299 
   10300     public List<ApplicationInfo> getRunningExternalApplications() {
   10301         enforceNotIsolatedCaller("getRunningExternalApplications");
   10302         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
   10303         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
   10304         if (runningApps != null && runningApps.size() > 0) {
   10305             Set<String> extList = new HashSet<String>();
   10306             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
   10307                 if (app.pkgList != null) {
   10308                     for (String pkg : app.pkgList) {
   10309                         extList.add(pkg);
   10310                     }
   10311                 }
   10312             }
   10313             IPackageManager pm = AppGlobals.getPackageManager();
   10314             for (String pkg : extList) {
   10315                 try {
   10316                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
   10317                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
   10318                         retList.add(info);
   10319                     }
   10320                 } catch (RemoteException e) {
   10321                 }
   10322             }
   10323         }
   10324         return retList;
   10325     }
   10326 
   10327     @Override
   10328     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
   10329         enforceNotIsolatedCaller("getMyMemoryState");
   10330         synchronized (this) {
   10331             ProcessRecord proc;
   10332             synchronized (mPidsSelfLocked) {
   10333                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
   10334             }
   10335             fillInProcMemInfo(proc, outInfo);
   10336         }
   10337     }
   10338 
   10339     @Override
   10340     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   10341         if (checkCallingPermission(android.Manifest.permission.DUMP)
   10342                 != PackageManager.PERMISSION_GRANTED) {
   10343             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   10344                     + Binder.getCallingPid()
   10345                     + ", uid=" + Binder.getCallingUid()
   10346                     + " without permission "
   10347                     + android.Manifest.permission.DUMP);
   10348             return;
   10349         }
   10350 
   10351         boolean dumpAll = false;
   10352         boolean dumpClient = false;
   10353         String dumpPackage = null;
   10354 
   10355         int opti = 0;
   10356         while (opti < args.length) {
   10357             String opt = args[opti];
   10358             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   10359                 break;
   10360             }
   10361             opti++;
   10362             if ("-a".equals(opt)) {
   10363                 dumpAll = true;
   10364             } else if ("-c".equals(opt)) {
   10365                 dumpClient = true;
   10366             } else if ("-h".equals(opt)) {
   10367                 pw.println("Activity manager dump options:");
   10368                 pw.println("  [-a] [-c] [-h] [cmd] ...");
   10369                 pw.println("  cmd may be one of:");
   10370                 pw.println("    a[ctivities]: activity stack state");
   10371                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
   10372                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
   10373                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
   10374                 pw.println("    o[om]: out of memory management");
   10375                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
   10376                 pw.println("    provider [COMP_SPEC]: provider client-side state");
   10377                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
   10378                 pw.println("    service [COMP_SPEC]: service client-side state");
   10379                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
   10380                 pw.println("    all: dump all activities");
   10381                 pw.println("    top: dump the top activity");
   10382                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
   10383                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
   10384                 pw.println("    a partial substring in a component name, a");
   10385                 pw.println("    hex object identifier.");
   10386                 pw.println("  -a: include all available server state.");
   10387                 pw.println("  -c: include client state.");
   10388                 return;
   10389             } else {
   10390                 pw.println("Unknown argument: " + opt + "; use -h for help");
   10391             }
   10392         }
   10393 
   10394         long origId = Binder.clearCallingIdentity();
   10395         boolean more = false;
   10396         // Is the caller requesting to dump a particular piece of data?
   10397         if (opti < args.length) {
   10398             String cmd = args[opti];
   10399             opti++;
   10400             if ("activities".equals(cmd) || "a".equals(cmd)) {
   10401                 synchronized (this) {
   10402                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
   10403                 }
   10404             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
   10405                 String[] newArgs;
   10406                 String name;
   10407                 if (opti >= args.length) {
   10408                     name = null;
   10409                     newArgs = EMPTY_STRING_ARRAY;
   10410                 } else {
   10411                     name = args[opti];
   10412                     opti++;
   10413                     newArgs = new String[args.length - opti];
   10414                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10415                             args.length - opti);
   10416                 }
   10417                 synchronized (this) {
   10418                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
   10419                 }
   10420             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
   10421                 String[] newArgs;
   10422                 String name;
   10423                 if (opti >= args.length) {
   10424                     name = null;
   10425                     newArgs = EMPTY_STRING_ARRAY;
   10426                 } else {
   10427                     name = args[opti];
   10428                     opti++;
   10429                     newArgs = new String[args.length - opti];
   10430                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10431                             args.length - opti);
   10432                 }
   10433                 synchronized (this) {
   10434                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
   10435                 }
   10436             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
   10437                 String[] newArgs;
   10438                 String name;
   10439                 if (opti >= args.length) {
   10440                     name = null;
   10441                     newArgs = EMPTY_STRING_ARRAY;
   10442                 } else {
   10443                     name = args[opti];
   10444                     opti++;
   10445                     newArgs = new String[args.length - opti];
   10446                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10447                             args.length - opti);
   10448                 }
   10449                 synchronized (this) {
   10450                     dumpProcessesLocked(fd, pw, args, opti, true, name);
   10451                 }
   10452             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
   10453                 synchronized (this) {
   10454                     dumpOomLocked(fd, pw, args, opti, true);
   10455                 }
   10456             } else if ("provider".equals(cmd)) {
   10457                 String[] newArgs;
   10458                 String name;
   10459                 if (opti >= args.length) {
   10460                     name = null;
   10461                     newArgs = EMPTY_STRING_ARRAY;
   10462                 } else {
   10463                     name = args[opti];
   10464                     opti++;
   10465                     newArgs = new String[args.length - opti];
   10466                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   10467                 }
   10468                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
   10469                     pw.println("No providers match: " + name);
   10470                     pw.println("Use -h for help.");
   10471                 }
   10472             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
   10473                 synchronized (this) {
   10474                     dumpProvidersLocked(fd, pw, args, opti, true, null);
   10475                 }
   10476             } else if ("service".equals(cmd)) {
   10477                 String[] newArgs;
   10478                 String name;
   10479                 if (opti >= args.length) {
   10480                     name = null;
   10481                     newArgs = EMPTY_STRING_ARRAY;
   10482                 } else {
   10483                     name = args[opti];
   10484                     opti++;
   10485                     newArgs = new String[args.length - opti];
   10486                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10487                             args.length - opti);
   10488                 }
   10489                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
   10490                     pw.println("No services match: " + name);
   10491                     pw.println("Use -h for help.");
   10492                 }
   10493             } else if ("package".equals(cmd)) {
   10494                 String[] newArgs;
   10495                 if (opti >= args.length) {
   10496                     pw.println("package: no package name specified");
   10497                     pw.println("Use -h for help.");
   10498                 } else {
   10499                     dumpPackage = args[opti];
   10500                     opti++;
   10501                     newArgs = new String[args.length - opti];
   10502                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
   10503                             args.length - opti);
   10504                     args = newArgs;
   10505                     opti = 0;
   10506                     more = true;
   10507                 }
   10508             } else if ("services".equals(cmd) || "s".equals(cmd)) {
   10509                 synchronized (this) {
   10510                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
   10511                 }
   10512             } else {
   10513                 // Dumping a single activity?
   10514                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
   10515                     pw.println("Bad activity command, or no activities match: " + cmd);
   10516                     pw.println("Use -h for help.");
   10517                 }
   10518             }
   10519             if (!more) {
   10520                 Binder.restoreCallingIdentity(origId);
   10521                 return;
   10522             }
   10523         }
   10524 
   10525         // No piece of data specified, dump everything.
   10526         synchronized (this) {
   10527             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10528             pw.println();
   10529             if (dumpAll) {
   10530                 pw.println("-------------------------------------------------------------------------------");
   10531             }
   10532             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10533             pw.println();
   10534             if (dumpAll) {
   10535                 pw.println("-------------------------------------------------------------------------------");
   10536             }
   10537             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10538             pw.println();
   10539             if (dumpAll) {
   10540                 pw.println("-------------------------------------------------------------------------------");
   10541             }
   10542             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10543             pw.println();
   10544             if (dumpAll) {
   10545                 pw.println("-------------------------------------------------------------------------------");
   10546             }
   10547             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
   10548             pw.println();
   10549             if (dumpAll) {
   10550                 pw.println("-------------------------------------------------------------------------------");
   10551             }
   10552             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
   10553         }
   10554         Binder.restoreCallingIdentity(origId);
   10555     }
   10556 
   10557     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10558             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
   10559         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
   10560 
   10561         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
   10562                 dumpPackage);
   10563         boolean needSep = printedAnything;
   10564 
   10565         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
   10566                 dumpPackage, needSep, "  mFocusedActivity: ");
   10567         if (printed) {
   10568             printedAnything = true;
   10569             needSep = false;
   10570         }
   10571 
   10572         if (dumpPackage == null) {
   10573             if (needSep) {
   10574                 pw.println();
   10575             }
   10576             needSep = true;
   10577             printedAnything = true;
   10578             mStackSupervisor.dump(pw, "  ");
   10579         }
   10580 
   10581         if (mRecentTasks.size() > 0) {
   10582             boolean printedHeader = false;
   10583 
   10584             final int N = mRecentTasks.size();
   10585             for (int i=0; i<N; i++) {
   10586                 TaskRecord tr = mRecentTasks.get(i);
   10587                 if (dumpPackage != null) {
   10588                     if (tr.realActivity == null ||
   10589                             !dumpPackage.equals(tr.realActivity)) {
   10590                         continue;
   10591                     }
   10592                 }
   10593                 if (!printedHeader) {
   10594                     if (needSep) {
   10595                         pw.println();
   10596                     }
   10597                     pw.println("  Recent tasks:");
   10598                     printedHeader = true;
   10599                     printedAnything = true;
   10600                 }
   10601                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
   10602                         pw.println(tr);
   10603                 if (dumpAll) {
   10604                     mRecentTasks.get(i).dump(pw, "    ");
   10605                 }
   10606             }
   10607         }
   10608 
   10609         if (!printedAnything) {
   10610             pw.println("  (nothing)");
   10611         }
   10612     }
   10613 
   10614     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   10615             int opti, boolean dumpAll, String dumpPackage) {
   10616         boolean needSep = false;
   10617         boolean printedAnything = false;
   10618         int numPers = 0;
   10619 
   10620         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
   10621 
   10622         if (dumpAll) {
   10623             final int NP = mProcessNames.getMap().size();
   10624             for (int ip=0; ip<NP; ip++) {
   10625                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
   10626                 final int NA = procs.size();
   10627                 for (int ia=0; ia<NA; ia++) {
   10628                     ProcessRecord r = procs.valueAt(ia);
   10629                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10630                         continue;
   10631                     }
   10632                     if (!needSep) {
   10633                         pw.println("  All known processes:");
   10634                         needSep = true;
   10635                         printedAnything = true;
   10636                     }
   10637                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
   10638                         pw.print(" UID "); pw.print(procs.keyAt(ia));
   10639                         pw.print(" "); pw.println(r);
   10640                     r.dump(pw, "    ");
   10641                     if (r.persistent) {
   10642                         numPers++;
   10643                     }
   10644                 }
   10645             }
   10646         }
   10647 
   10648         if (mIsolatedProcesses.size() > 0) {
   10649             boolean printed = false;
   10650             for (int i=0; i<mIsolatedProcesses.size(); i++) {
   10651                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
   10652                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10653                     continue;
   10654                 }
   10655                 if (!printed) {
   10656                     if (needSep) {
   10657                         pw.println();
   10658                     }
   10659                     pw.println("  Isolated process list (sorted by uid):");
   10660                     printedAnything = true;
   10661                     printed = true;
   10662                     needSep = true;
   10663                 }
   10664                 pw.println(String.format("%sIsolated #%2d: %s",
   10665                         "    ", i, r.toString()));
   10666             }
   10667         }
   10668 
   10669         if (mLruProcesses.size() > 0) {
   10670             if (needSep) {
   10671                 pw.println();
   10672             }
   10673             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
   10674                     pw.print(" total, non-act at ");
   10675                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   10676                     pw.print(", non-svc at ");
   10677                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   10678                     pw.println("):");
   10679             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
   10680             needSep = true;
   10681             printedAnything = true;
   10682         }
   10683 
   10684         if (dumpAll || dumpPackage != null) {
   10685             synchronized (mPidsSelfLocked) {
   10686                 boolean printed = false;
   10687                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
   10688                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
   10689                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   10690                         continue;
   10691                     }
   10692                     if (!printed) {
   10693                         if (needSep) pw.println();
   10694                         needSep = true;
   10695                         pw.println("  PID mappings:");
   10696                         printed = true;
   10697                         printedAnything = true;
   10698                     }
   10699                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
   10700                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
   10701                 }
   10702             }
   10703         }
   10704 
   10705         if (mForegroundProcesses.size() > 0) {
   10706             synchronized (mPidsSelfLocked) {
   10707                 boolean printed = false;
   10708                 for (int i=0; i<mForegroundProcesses.size(); i++) {
   10709                     ProcessRecord r = mPidsSelfLocked.get(
   10710                             mForegroundProcesses.valueAt(i).pid);
   10711                     if (dumpPackage != null && (r == null
   10712                             || !r.pkgList.containsKey(dumpPackage))) {
   10713                         continue;
   10714                     }
   10715                     if (!printed) {
   10716                         if (needSep) pw.println();
   10717                         needSep = true;
   10718                         pw.println("  Foreground Processes:");
   10719                         printed = true;
   10720                         printedAnything = true;
   10721                     }
   10722                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
   10723                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
   10724                 }
   10725             }
   10726         }
   10727 
   10728         if (mPersistentStartingProcesses.size() > 0) {
   10729             if (needSep) pw.println();
   10730             needSep = true;
   10731             printedAnything = true;
   10732             pw.println("  Persisent processes that are starting:");
   10733             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
   10734                     "Starting Norm", "Restarting PERS", dumpPackage);
   10735         }
   10736 
   10737         if (mRemovedProcesses.size() > 0) {
   10738             if (needSep) pw.println();
   10739             needSep = true;
   10740             printedAnything = true;
   10741             pw.println("  Processes that are being removed:");
   10742             dumpProcessList(pw, this, mRemovedProcesses, "    ",
   10743                     "Removed Norm", "Removed PERS", dumpPackage);
   10744         }
   10745 
   10746         if (mProcessesOnHold.size() > 0) {
   10747             if (needSep) pw.println();
   10748             needSep = true;
   10749             printedAnything = true;
   10750             pw.println("  Processes that are on old until the system is ready:");
   10751             dumpProcessList(pw, this, mProcessesOnHold, "    ",
   10752                     "OnHold Norm", "OnHold PERS", dumpPackage);
   10753         }
   10754 
   10755         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
   10756 
   10757         if (mProcessCrashTimes.getMap().size() > 0) {
   10758             boolean printed = false;
   10759             long now = SystemClock.uptimeMillis();
   10760             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
   10761             final int NP = pmap.size();
   10762             for (int ip=0; ip<NP; ip++) {
   10763                 String pname = pmap.keyAt(ip);
   10764                 SparseArray<Long> uids = pmap.valueAt(ip);
   10765                 final int N = uids.size();
   10766                 for (int i=0; i<N; i++) {
   10767                     int puid = uids.keyAt(i);
   10768                     ProcessRecord r = mProcessNames.get(pname, puid);
   10769                     if (dumpPackage != null && (r == null
   10770                             || !r.pkgList.containsKey(dumpPackage))) {
   10771                         continue;
   10772                     }
   10773                     if (!printed) {
   10774                         if (needSep) pw.println();
   10775                         needSep = true;
   10776                         pw.println("  Time since processes crashed:");
   10777                         printed = true;
   10778                         printedAnything = true;
   10779                     }
   10780                     pw.print("    Process "); pw.print(pname);
   10781                             pw.print(" uid "); pw.print(puid);
   10782                             pw.print(": last crashed ");
   10783                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
   10784                             pw.println(" ago");
   10785                 }
   10786             }
   10787         }
   10788 
   10789         if (mBadProcesses.getMap().size() > 0) {
   10790             boolean printed = false;
   10791             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
   10792             final int NP = pmap.size();
   10793             for (int ip=0; ip<NP; ip++) {
   10794                 String pname = pmap.keyAt(ip);
   10795                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
   10796                 final int N = uids.size();
   10797                 for (int i=0; i<N; i++) {
   10798                     int puid = uids.keyAt(i);
   10799                     ProcessRecord r = mProcessNames.get(pname, puid);
   10800                     if (dumpPackage != null && (r == null
   10801                             || !r.pkgList.containsKey(dumpPackage))) {
   10802                         continue;
   10803                     }
   10804                     if (!printed) {
   10805                         if (needSep) pw.println();
   10806                         needSep = true;
   10807                         pw.println("  Bad processes:");
   10808                         printedAnything = true;
   10809                     }
   10810                     BadProcessInfo info = uids.valueAt(i);
   10811                     pw.print("    Bad process "); pw.print(pname);
   10812                             pw.print(" uid "); pw.print(puid);
   10813                             pw.print(": crashed at time "); pw.println(info.time);
   10814                     if (info.shortMsg != null) {
   10815                         pw.print("      Short msg: "); pw.println(info.shortMsg);
   10816                     }
   10817                     if (info.longMsg != null) {
   10818                         pw.print("      Long msg: "); pw.println(info.longMsg);
   10819                     }
   10820                     if (info.stack != null) {
   10821                         pw.println("      Stack:");
   10822                         int lastPos = 0;
   10823                         for (int pos=0; pos<info.stack.length(); pos++) {
   10824                             if (info.stack.charAt(pos) == '\n') {
   10825                                 pw.print("        ");
   10826                                 pw.write(info.stack, lastPos, pos-lastPos);
   10827                                 pw.println();
   10828                                 lastPos = pos+1;
   10829                             }
   10830                         }
   10831                         if (lastPos < info.stack.length()) {
   10832                             pw.print("        ");
   10833                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
   10834                             pw.println();
   10835                         }
   10836                     }
   10837                 }
   10838             }
   10839         }
   10840 
   10841         if (dumpPackage == null) {
   10842             pw.println();
   10843             needSep = false;
   10844             pw.println("  mStartedUsers:");
   10845             for (int i=0; i<mStartedUsers.size(); i++) {
   10846                 UserStartedState uss = mStartedUsers.valueAt(i);
   10847                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
   10848                         pw.print(": "); uss.dump("", pw);
   10849             }
   10850             pw.print("  mStartedUserArray: [");
   10851             for (int i=0; i<mStartedUserArray.length; i++) {
   10852                 if (i > 0) pw.print(", ");
   10853                 pw.print(mStartedUserArray[i]);
   10854             }
   10855             pw.println("]");
   10856             pw.print("  mUserLru: [");
   10857             for (int i=0; i<mUserLru.size(); i++) {
   10858                 if (i > 0) pw.print(", ");
   10859                 pw.print(mUserLru.get(i));
   10860             }
   10861             pw.println("]");
   10862             if (dumpAll) {
   10863                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
   10864             }
   10865         }
   10866         if (mHomeProcess != null && (dumpPackage == null
   10867                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
   10868             if (needSep) {
   10869                 pw.println();
   10870                 needSep = false;
   10871             }
   10872             pw.println("  mHomeProcess: " + mHomeProcess);
   10873         }
   10874         if (mPreviousProcess != null && (dumpPackage == null
   10875                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
   10876             if (needSep) {
   10877                 pw.println();
   10878                 needSep = false;
   10879             }
   10880             pw.println("  mPreviousProcess: " + mPreviousProcess);
   10881         }
   10882         if (dumpAll) {
   10883             StringBuilder sb = new StringBuilder(128);
   10884             sb.append("  mPreviousProcessVisibleTime: ");
   10885             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
   10886             pw.println(sb);
   10887         }
   10888         if (mHeavyWeightProcess != null && (dumpPackage == null
   10889                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
   10890             if (needSep) {
   10891                 pw.println();
   10892                 needSep = false;
   10893             }
   10894             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   10895         }
   10896         if (dumpPackage == null) {
   10897             pw.println("  mConfiguration: " + mConfiguration);
   10898         }
   10899         if (dumpAll) {
   10900             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
   10901             if (mCompatModePackages.getPackages().size() > 0) {
   10902                 boolean printed = false;
   10903                 for (Map.Entry<String, Integer> entry
   10904                         : mCompatModePackages.getPackages().entrySet()) {
   10905                     String pkg = entry.getKey();
   10906                     int mode = entry.getValue();
   10907                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
   10908                         continue;
   10909                     }
   10910                     if (!printed) {
   10911                         pw.println("  mScreenCompatPackages:");
   10912                         printed = true;
   10913                     }
   10914                     pw.print("    "); pw.print(pkg); pw.print(": ");
   10915                             pw.print(mode); pw.println();
   10916                 }
   10917             }
   10918         }
   10919         if (dumpPackage == null) {
   10920             if (mSleeping || mWentToSleep || mLockScreenShown) {
   10921                 pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
   10922                         + " mLockScreenShown " + mLockScreenShown);
   10923             }
   10924             if (mShuttingDown) {
   10925                 pw.println("  mShuttingDown=" + mShuttingDown);
   10926             }
   10927         }
   10928         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
   10929                 || mOrigWaitForDebugger) {
   10930             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
   10931                     || dumpPackage.equals(mOrigDebugApp)) {
   10932                 if (needSep) {
   10933                     pw.println();
   10934                     needSep = false;
   10935                 }
   10936                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
   10937                         + " mDebugTransient=" + mDebugTransient
   10938                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
   10939             }
   10940         }
   10941         if (mOpenGlTraceApp != null) {
   10942             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
   10943                 if (needSep) {
   10944                     pw.println();
   10945                     needSep = false;
   10946                 }
   10947                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
   10948             }
   10949         }
   10950         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
   10951                 || mProfileFd != null) {
   10952             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
   10953                 if (needSep) {
   10954                     pw.println();
   10955                     needSep = false;
   10956                 }
   10957                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
   10958                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
   10959                 pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
   10960                         + mAutoStopProfiler);
   10961             }
   10962         }
   10963         if (dumpPackage == null) {
   10964             if (mAlwaysFinishActivities || mController != null) {
   10965                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
   10966                         + " mController=" + mController);
   10967             }
   10968             if (dumpAll) {
   10969                 pw.println("  Total persistent processes: " + numPers);
   10970                 pw.println("  mStartRunning=" + mStartRunning
   10971                         + " mProcessesReady=" + mProcessesReady
   10972                         + " mSystemReady=" + mSystemReady);
   10973                 pw.println("  mBooting=" + mBooting
   10974                         + " mBooted=" + mBooted
   10975                         + " mFactoryTest=" + mFactoryTest);
   10976                 pw.print("  mLastPowerCheckRealtime=");
   10977                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
   10978                         pw.println("");
   10979                 pw.print("  mLastPowerCheckUptime=");
   10980                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
   10981                         pw.println("");
   10982                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
   10983                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
   10984                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
   10985                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
   10986                         + " (" + mLruProcesses.size() + " total)"
   10987                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
   10988                         + " mNumServiceProcs=" + mNumServiceProcs
   10989                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
   10990                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
   10991                         + " mLastMemoryLevel" + mLastMemoryLevel
   10992                         + " mLastNumProcesses" + mLastNumProcesses);
   10993                 long now = SystemClock.uptimeMillis();
   10994                 pw.print("  mLastIdleTime=");
   10995                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
   10996                         pw.print(" mLowRamSinceLastIdle=");
   10997                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
   10998                         pw.println();
   10999             }
   11000         }
   11001 
   11002         if (!printedAnything) {
   11003             pw.println("  (nothing)");
   11004         }
   11005     }
   11006 
   11007     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
   11008             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
   11009         if (mProcessesToGc.size() > 0) {
   11010             boolean printed = false;
   11011             long now = SystemClock.uptimeMillis();
   11012             for (int i=0; i<mProcessesToGc.size(); i++) {
   11013                 ProcessRecord proc = mProcessesToGc.get(i);
   11014                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
   11015                     continue;
   11016                 }
   11017                 if (!printed) {
   11018                     if (needSep) pw.println();
   11019                     needSep = true;
   11020                     pw.println("  Processes that are waiting to GC:");
   11021                     printed = true;
   11022                 }
   11023                 pw.print("    Process "); pw.println(proc);
   11024                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
   11025                         pw.print(", last gced=");
   11026                         pw.print(now-proc.lastRequestedGc);
   11027                         pw.print(" ms ago, last lowMem=");
   11028                         pw.print(now-proc.lastLowMemory);
   11029                         pw.println(" ms ago");
   11030 
   11031             }
   11032         }
   11033         return needSep;
   11034     }
   11035 
   11036     void printOomLevel(PrintWriter pw, String name, int adj) {
   11037         pw.print("    ");
   11038         if (adj >= 0) {
   11039             pw.print(' ');
   11040             if (adj < 10) pw.print(' ');
   11041         } else {
   11042             if (adj > -10) pw.print(' ');
   11043         }
   11044         pw.print(adj);
   11045         pw.print(": ");
   11046         pw.print(name);
   11047         pw.print(" (");
   11048         pw.print(mProcessList.getMemLevel(adj)/1024);
   11049         pw.println(" kB)");
   11050     }
   11051 
   11052     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11053             int opti, boolean dumpAll) {
   11054         boolean needSep = false;
   11055 
   11056         if (mLruProcesses.size() > 0) {
   11057             if (needSep) pw.println();
   11058             needSep = true;
   11059             pw.println("  OOM levels:");
   11060             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
   11061             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
   11062             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
   11063             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
   11064             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
   11065             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
   11066             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
   11067             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
   11068             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
   11069             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
   11070             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
   11071             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
   11072             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
   11073 
   11074             if (needSep) pw.println();
   11075             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
   11076                     pw.print(" total, non-act at ");
   11077                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
   11078                     pw.print(", non-svc at ");
   11079                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
   11080                     pw.println("):");
   11081             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
   11082             needSep = true;
   11083         }
   11084 
   11085         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
   11086 
   11087         pw.println();
   11088         pw.println("  mHomeProcess: " + mHomeProcess);
   11089         pw.println("  mPreviousProcess: " + mPreviousProcess);
   11090         if (mHeavyWeightProcess != null) {
   11091             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
   11092         }
   11093 
   11094         return true;
   11095     }
   11096 
   11097     /**
   11098      * There are three ways to call this:
   11099      *  - no provider specified: dump all the providers
   11100      *  - a flattened component name that matched an existing provider was specified as the
   11101      *    first arg: dump that one provider
   11102      *  - the first arg isn't the flattened component name of an existing provider:
   11103      *    dump all providers whose component contains the first arg as a substring
   11104      */
   11105     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   11106             int opti, boolean dumpAll) {
   11107         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
   11108     }
   11109 
   11110     static class ItemMatcher {
   11111         ArrayList<ComponentName> components;
   11112         ArrayList<String> strings;
   11113         ArrayList<Integer> objects;
   11114         boolean all;
   11115 
   11116         ItemMatcher() {
   11117             all = true;
   11118         }
   11119 
   11120         void build(String name) {
   11121             ComponentName componentName = ComponentName.unflattenFromString(name);
   11122             if (componentName != null) {
   11123                 if (components == null) {
   11124                     components = new ArrayList<ComponentName>();
   11125                 }
   11126                 components.add(componentName);
   11127                 all = false;
   11128             } else {
   11129                 int objectId = 0;
   11130                 // Not a '/' separated full component name; maybe an object ID?
   11131                 try {
   11132                     objectId = Integer.parseInt(name, 16);
   11133                     if (objects == null) {
   11134                         objects = new ArrayList<Integer>();
   11135                     }
   11136                     objects.add(objectId);
   11137                     all = false;
   11138                 } catch (RuntimeException e) {
   11139                     // Not an integer; just do string match.
   11140                     if (strings == null) {
   11141                         strings = new ArrayList<String>();
   11142                     }
   11143                     strings.add(name);
   11144                     all = false;
   11145                 }
   11146             }
   11147         }
   11148 
   11149         int build(String[] args, int opti) {
   11150             for (; opti<args.length; opti++) {
   11151                 String name = args[opti];
   11152                 if ("--".equals(name)) {
   11153                     return opti+1;
   11154                 }
   11155                 build(name);
   11156             }
   11157             return opti;
   11158         }
   11159 
   11160         boolean match(Object object, ComponentName comp) {
   11161             if (all) {
   11162                 return true;
   11163             }
   11164             if (components != null) {
   11165                 for (int i=0; i<components.size(); i++) {
   11166                     if (components.get(i).equals(comp)) {
   11167                         return true;
   11168                     }
   11169                 }
   11170             }
   11171             if (objects != null) {
   11172                 for (int i=0; i<objects.size(); i++) {
   11173                     if (System.identityHashCode(object) == objects.get(i)) {
   11174                         return true;
   11175                     }
   11176                 }
   11177             }
   11178             if (strings != null) {
   11179                 String flat = comp.flattenToString();
   11180                 for (int i=0; i<strings.size(); i++) {
   11181                     if (flat.contains(strings.get(i))) {
   11182                         return true;
   11183                     }
   11184                 }
   11185             }
   11186             return false;
   11187         }
   11188     }
   11189 
   11190     /**
   11191      * There are three things that cmd can be:
   11192      *  - a flattened component name that matches an existing activity
   11193      *  - the cmd arg isn't the flattened component name of an existing activity:
   11194      *    dump all activity whose component contains the cmd as a substring
   11195      *  - A hex number of the ActivityRecord object instance.
   11196      */
   11197     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
   11198             int opti, boolean dumpAll) {
   11199         ArrayList<ActivityRecord> activities;
   11200 
   11201         synchronized (this) {
   11202             activities = mStackSupervisor.getDumpActivitiesLocked(name);
   11203         }
   11204 
   11205         if (activities.size() <= 0) {
   11206             return false;
   11207         }
   11208 
   11209         String[] newArgs = new String[args.length - opti];
   11210         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
   11211 
   11212         TaskRecord lastTask = null;
   11213         boolean needSep = false;
   11214         for (int i=activities.size()-1; i>=0; i--) {
   11215             ActivityRecord r = activities.get(i);
   11216             if (needSep) {
   11217                 pw.println();
   11218             }
   11219             needSep = true;
   11220             synchronized (this) {
   11221                 if (lastTask != r.task) {
   11222                     lastTask = r.task;
   11223                     pw.print("TASK "); pw.print(lastTask.affinity);
   11224                             pw.print(" id="); pw.println(lastTask.taskId);
   11225                     if (dumpAll) {
   11226                         lastTask.dump(pw, "  ");
   11227                     }
   11228                 }
   11229             }
   11230             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
   11231         }
   11232         return true;
   11233     }
   11234 
   11235     /**
   11236      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
   11237      * there is a thread associated with the activity.
   11238      */
   11239     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
   11240             final ActivityRecord r, String[] args, boolean dumpAll) {
   11241         String innerPrefix = prefix + "  ";
   11242         synchronized (this) {
   11243             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
   11244                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
   11245                     pw.print(" pid=");
   11246                     if (r.app != null) pw.println(r.app.pid);
   11247                     else pw.println("(not running)");
   11248             if (dumpAll) {
   11249                 r.dump(pw, innerPrefix);
   11250             }
   11251         }
   11252         if (r.app != null && r.app.thread != null) {
   11253             // flush anything that is already in the PrintWriter since the thread is going
   11254             // to write to the file descriptor directly
   11255             pw.flush();
   11256             try {
   11257                 TransferPipe tp = new TransferPipe();
   11258                 try {
   11259                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
   11260                             r.appToken, innerPrefix, args);
   11261                     tp.go(fd);
   11262                 } finally {
   11263                     tp.kill();
   11264                 }
   11265             } catch (IOException e) {
   11266                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
   11267             } catch (RemoteException e) {
   11268                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
   11269             }
   11270         }
   11271     }
   11272 
   11273     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11274             int opti, boolean dumpAll, String dumpPackage) {
   11275         boolean needSep = false;
   11276         boolean onlyHistory = false;
   11277         boolean printedAnything = false;
   11278 
   11279         if ("history".equals(dumpPackage)) {
   11280             if (opti < args.length && "-s".equals(args[opti])) {
   11281                 dumpAll = false;
   11282             }
   11283             onlyHistory = true;
   11284             dumpPackage = null;
   11285         }
   11286 
   11287         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
   11288         if (!onlyHistory && dumpAll) {
   11289             if (mRegisteredReceivers.size() > 0) {
   11290                 boolean printed = false;
   11291                 Iterator it = mRegisteredReceivers.values().iterator();
   11292                 while (it.hasNext()) {
   11293                     ReceiverList r = (ReceiverList)it.next();
   11294                     if (dumpPackage != null && (r.app == null ||
   11295                             !dumpPackage.equals(r.app.info.packageName))) {
   11296                         continue;
   11297                     }
   11298                     if (!printed) {
   11299                         pw.println("  Registered Receivers:");
   11300                         needSep = true;
   11301                         printed = true;
   11302                         printedAnything = true;
   11303                     }
   11304                     pw.print("  * "); pw.println(r);
   11305                     r.dump(pw, "    ");
   11306                 }
   11307             }
   11308 
   11309             if (mReceiverResolver.dump(pw, needSep ?
   11310                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
   11311                     "    ", dumpPackage, false)) {
   11312                 needSep = true;
   11313                 printedAnything = true;
   11314             }
   11315         }
   11316 
   11317         for (BroadcastQueue q : mBroadcastQueues) {
   11318             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
   11319             printedAnything |= needSep;
   11320         }
   11321 
   11322         needSep = true;
   11323 
   11324         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
   11325             for (int user=0; user<mStickyBroadcasts.size(); user++) {
   11326                 if (needSep) {
   11327                     pw.println();
   11328                 }
   11329                 needSep = true;
   11330                 printedAnything = true;
   11331                 pw.print("  Sticky broadcasts for user ");
   11332                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
   11333                 StringBuilder sb = new StringBuilder(128);
   11334                 for (Map.Entry<String, ArrayList<Intent>> ent
   11335                         : mStickyBroadcasts.valueAt(user).entrySet()) {
   11336                     pw.print("  * Sticky action "); pw.print(ent.getKey());
   11337                     if (dumpAll) {
   11338                         pw.println(":");
   11339                         ArrayList<Intent> intents = ent.getValue();
   11340                         final int N = intents.size();
   11341                         for (int i=0; i<N; i++) {
   11342                             sb.setLength(0);
   11343                             sb.append("    Intent: ");
   11344                             intents.get(i).toShortString(sb, false, true, false, false);
   11345                             pw.println(sb.toString());
   11346                             Bundle bundle = intents.get(i).getExtras();
   11347                             if (bundle != null) {
   11348                                 pw.print("      ");
   11349                                 pw.println(bundle.toString());
   11350                             }
   11351                         }
   11352                     } else {
   11353                         pw.println("");
   11354                     }
   11355                 }
   11356             }
   11357         }
   11358 
   11359         if (!onlyHistory && dumpAll) {
   11360             pw.println();
   11361             for (BroadcastQueue queue : mBroadcastQueues) {
   11362                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
   11363                         + queue.mBroadcastsScheduled);
   11364             }
   11365             pw.println("  mHandler:");
   11366             mHandler.dump(new PrintWriterPrinter(pw), "    ");
   11367             needSep = true;
   11368             printedAnything = true;
   11369         }
   11370 
   11371         if (!printedAnything) {
   11372             pw.println("  (nothing)");
   11373         }
   11374     }
   11375 
   11376     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11377             int opti, boolean dumpAll, String dumpPackage) {
   11378         boolean needSep;
   11379         boolean printedAnything = false;
   11380 
   11381         ItemMatcher matcher = new ItemMatcher();
   11382         matcher.build(args, opti);
   11383 
   11384         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
   11385 
   11386         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
   11387         printedAnything |= needSep;
   11388 
   11389         if (mLaunchingProviders.size() > 0) {
   11390             boolean printed = false;
   11391             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
   11392                 ContentProviderRecord r = mLaunchingProviders.get(i);
   11393                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
   11394                     continue;
   11395                 }
   11396                 if (!printed) {
   11397                     if (needSep) pw.println();
   11398                     needSep = true;
   11399                     pw.println("  Launching content providers:");
   11400                     printed = true;
   11401                     printedAnything = true;
   11402                 }
   11403                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
   11404                         pw.println(r);
   11405             }
   11406         }
   11407 
   11408         if (mGrantedUriPermissions.size() > 0) {
   11409             boolean printed = false;
   11410             int dumpUid = -2;
   11411             if (dumpPackage != null) {
   11412                 try {
   11413                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
   11414                 } catch (NameNotFoundException e) {
   11415                     dumpUid = -1;
   11416                 }
   11417             }
   11418             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
   11419                 int uid = mGrantedUriPermissions.keyAt(i);
   11420                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
   11421                     continue;
   11422                 }
   11423                 ArrayMap<Uri, UriPermission> perms
   11424                         = mGrantedUriPermissions.valueAt(i);
   11425                 if (!printed) {
   11426                     if (needSep) pw.println();
   11427                     needSep = true;
   11428                     pw.println("  Granted Uri Permissions:");
   11429                     printed = true;
   11430                     printedAnything = true;
   11431                 }
   11432                 pw.print("  * UID "); pw.print(uid);
   11433                         pw.println(" holds:");
   11434                 for (UriPermission perm : perms.values()) {
   11435                     pw.print("    "); pw.println(perm);
   11436                     if (dumpAll) {
   11437                         perm.dump(pw, "      ");
   11438                     }
   11439                 }
   11440             }
   11441         }
   11442 
   11443         if (!printedAnything) {
   11444             pw.println("  (nothing)");
   11445         }
   11446     }
   11447 
   11448     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
   11449             int opti, boolean dumpAll, String dumpPackage) {
   11450         boolean printed = false;
   11451 
   11452         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
   11453 
   11454         if (mIntentSenderRecords.size() > 0) {
   11455             Iterator<WeakReference<PendingIntentRecord>> it
   11456                     = mIntentSenderRecords.values().iterator();
   11457             while (it.hasNext()) {
   11458                 WeakReference<PendingIntentRecord> ref = it.next();
   11459                 PendingIntentRecord rec = ref != null ? ref.get(): null;
   11460                 if (dumpPackage != null && (rec == null
   11461                         || !dumpPackage.equals(rec.key.packageName))) {
   11462                     continue;
   11463                 }
   11464                 printed = true;
   11465                 if (rec != null) {
   11466                     pw.print("  * "); pw.println(rec);
   11467                     if (dumpAll) {
   11468                         rec.dump(pw, "    ");
   11469                     }
   11470                 } else {
   11471                     pw.print("  * "); pw.println(ref);
   11472                 }
   11473             }
   11474         }
   11475 
   11476         if (!printed) {
   11477             pw.println("  (nothing)");
   11478         }
   11479     }
   11480 
   11481     private static final int dumpProcessList(PrintWriter pw,
   11482             ActivityManagerService service, List list,
   11483             String prefix, String normalLabel, String persistentLabel,
   11484             String dumpPackage) {
   11485         int numPers = 0;
   11486         final int N = list.size()-1;
   11487         for (int i=N; i>=0; i--) {
   11488             ProcessRecord r = (ProcessRecord)list.get(i);
   11489             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
   11490                 continue;
   11491             }
   11492             pw.println(String.format("%s%s #%2d: %s",
   11493                     prefix, (r.persistent ? persistentLabel : normalLabel),
   11494                     i, r.toString()));
   11495             if (r.persistent) {
   11496                 numPers++;
   11497             }
   11498         }
   11499         return numPers;
   11500     }
   11501 
   11502     private static final boolean dumpProcessOomList(PrintWriter pw,
   11503             ActivityManagerService service, List<ProcessRecord> origList,
   11504             String prefix, String normalLabel, String persistentLabel,
   11505             boolean inclDetails, String dumpPackage) {
   11506 
   11507         ArrayList<Pair<ProcessRecord, Integer>> list
   11508                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
   11509         for (int i=0; i<origList.size(); i++) {
   11510             ProcessRecord r = origList.get(i);
   11511             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
   11512                 continue;
   11513             }
   11514             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
   11515         }
   11516 
   11517         if (list.size() <= 0) {
   11518             return false;
   11519         }
   11520 
   11521         Comparator<Pair<ProcessRecord, Integer>> comparator
   11522                 = new Comparator<Pair<ProcessRecord, Integer>>() {
   11523             @Override
   11524             public int compare(Pair<ProcessRecord, Integer> object1,
   11525                     Pair<ProcessRecord, Integer> object2) {
   11526                 if (object1.first.setAdj != object2.first.setAdj) {
   11527                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
   11528                 }
   11529                 if (object1.second.intValue() != object2.second.intValue()) {
   11530                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
   11531                 }
   11532                 return 0;
   11533             }
   11534         };
   11535 
   11536         Collections.sort(list, comparator);
   11537 
   11538         final long curRealtime = SystemClock.elapsedRealtime();
   11539         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
   11540         final long curUptime = SystemClock.uptimeMillis();
   11541         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
   11542 
   11543         for (int i=list.size()-1; i>=0; i--) {
   11544             ProcessRecord r = list.get(i).first;
   11545             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
   11546             char schedGroup;
   11547             switch (r.setSchedGroup) {
   11548                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
   11549                     schedGroup = 'B';
   11550                     break;
   11551                 case Process.THREAD_GROUP_DEFAULT:
   11552                     schedGroup = 'F';
   11553                     break;
   11554                 default:
   11555                     schedGroup = '?';
   11556                     break;
   11557             }
   11558             char foreground;
   11559             if (r.foregroundActivities) {
   11560                 foreground = 'A';
   11561             } else if (r.foregroundServices) {
   11562                 foreground = 'S';
   11563             } else {
   11564                 foreground = ' ';
   11565             }
   11566             String procState = ProcessList.makeProcStateString(r.curProcState);
   11567             pw.print(prefix);
   11568             pw.print(r.persistent ? persistentLabel : normalLabel);
   11569             pw.print(" #");
   11570             int num = (origList.size()-1)-list.get(i).second;
   11571             if (num < 10) pw.print(' ');
   11572             pw.print(num);
   11573             pw.print(": ");
   11574             pw.print(oomAdj);
   11575             pw.print(' ');
   11576             pw.print(schedGroup);
   11577             pw.print('/');
   11578             pw.print(foreground);
   11579             pw.print('/');
   11580             pw.print(procState);
   11581             pw.print(" trm:");
   11582             if (r.trimMemoryLevel < 10) pw.print(' ');
   11583             pw.print(r.trimMemoryLevel);
   11584             pw.print(' ');
   11585             pw.print(r.toShortString());
   11586             pw.print(" (");
   11587             pw.print(r.adjType);
   11588             pw.println(')');
   11589             if (r.adjSource != null || r.adjTarget != null) {
   11590                 pw.print(prefix);
   11591                 pw.print("    ");
   11592                 if (r.adjTarget instanceof ComponentName) {
   11593                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
   11594                 } else if (r.adjTarget != null) {
   11595                     pw.print(r.adjTarget.toString());
   11596                 } else {
   11597                     pw.print("{null}");
   11598                 }
   11599                 pw.print("<=");
   11600                 if (r.adjSource instanceof ProcessRecord) {
   11601                     pw.print("Proc{");
   11602                     pw.print(((ProcessRecord)r.adjSource).toShortString());
   11603                     pw.println("}");
   11604                 } else if (r.adjSource != null) {
   11605                     pw.println(r.adjSource.toString());
   11606                 } else {
   11607                     pw.println("{null}");
   11608                 }
   11609             }
   11610             if (inclDetails) {
   11611                 pw.print(prefix);
   11612                 pw.print("    ");
   11613                 pw.print("oom: max="); pw.print(r.maxAdj);
   11614                 pw.print(" curRaw="); pw.print(r.curRawAdj);
   11615                 pw.print(" setRaw="); pw.print(r.setRawAdj);
   11616                 pw.print(" cur="); pw.print(r.curAdj);
   11617                 pw.print(" set="); pw.println(r.setAdj);
   11618                 pw.print(prefix);
   11619                 pw.print("    ");
   11620                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
   11621                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
   11622                 pw.print(" lastPss="); pw.print(r.lastPss);
   11623                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
   11624                 pw.print(prefix);
   11625                 pw.print("    ");
   11626                 pw.print("keeping="); pw.print(r.keeping);
   11627                 pw.print(" cached="); pw.print(r.cached);
   11628                 pw.print(" empty="); pw.print(r.empty);
   11629                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
   11630 
   11631                 if (!r.keeping) {
   11632                     if (r.lastWakeTime != 0) {
   11633                         long wtime;
   11634                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
   11635                         synchronized (stats) {
   11636                             wtime = stats.getProcessWakeTime(r.info.uid,
   11637                                     r.pid, curRealtime);
   11638                         }
   11639                         long timeUsed = wtime - r.lastWakeTime;
   11640                         pw.print(prefix);
   11641                         pw.print("    ");
   11642                         pw.print("keep awake over ");
   11643                         TimeUtils.formatDuration(realtimeSince, pw);
   11644                         pw.print(" used ");
   11645                         TimeUtils.formatDuration(timeUsed, pw);
   11646                         pw.print(" (");
   11647                         pw.print((timeUsed*100)/realtimeSince);
   11648                         pw.println("%)");
   11649                     }
   11650                     if (r.lastCpuTime != 0) {
   11651                         long timeUsed = r.curCpuTime - r.lastCpuTime;
   11652                         pw.print(prefix);
   11653                         pw.print("    ");
   11654                         pw.print("run cpu over ");
   11655                         TimeUtils.formatDuration(uptimeSince, pw);
   11656                         pw.print(" used ");
   11657                         TimeUtils.formatDuration(timeUsed, pw);
   11658                         pw.print(" (");
   11659                         pw.print((timeUsed*100)/uptimeSince);
   11660                         pw.println("%)");
   11661                     }
   11662                 }
   11663             }
   11664         }
   11665         return true;
   11666     }
   11667 
   11668     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
   11669         ArrayList<ProcessRecord> procs;
   11670         synchronized (this) {
   11671             if (args != null && args.length > start
   11672                     && args[start].charAt(0) != '-') {
   11673                 procs = new ArrayList<ProcessRecord>();
   11674                 int pid = -1;
   11675                 try {
   11676                     pid = Integer.parseInt(args[start]);
   11677                 } catch (NumberFormatException e) {
   11678                 }
   11679                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   11680                     ProcessRecord proc = mLruProcesses.get(i);
   11681                     if (proc.pid == pid) {
   11682                         procs.add(proc);
   11683                     } else if (proc.processName.equals(args[start])) {
   11684                         procs.add(proc);
   11685                     }
   11686                 }
   11687                 if (procs.size() <= 0) {
   11688                     return null;
   11689                 }
   11690             } else {
   11691                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
   11692             }
   11693         }
   11694         return procs;
   11695     }
   11696 
   11697     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
   11698             PrintWriter pw, String[] args) {
   11699         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11700         if (procs == null) {
   11701             pw.println("No process found for: " + args[0]);
   11702             return;
   11703         }
   11704 
   11705         long uptime = SystemClock.uptimeMillis();
   11706         long realtime = SystemClock.elapsedRealtime();
   11707         pw.println("Applications Graphics Acceleration Info:");
   11708         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11709 
   11710         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11711             ProcessRecord r = procs.get(i);
   11712             if (r.thread != null) {
   11713                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
   11714                 pw.flush();
   11715                 try {
   11716                     TransferPipe tp = new TransferPipe();
   11717                     try {
   11718                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
   11719                         tp.go(fd);
   11720                     } finally {
   11721                         tp.kill();
   11722                     }
   11723                 } catch (IOException e) {
   11724                     pw.println("Failure while dumping the app: " + r);
   11725                     pw.flush();
   11726                 } catch (RemoteException e) {
   11727                     pw.println("Got a RemoteException while dumping the app " + r);
   11728                     pw.flush();
   11729                 }
   11730             }
   11731         }
   11732     }
   11733 
   11734     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
   11735         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
   11736         if (procs == null) {
   11737             pw.println("No process found for: " + args[0]);
   11738             return;
   11739         }
   11740 
   11741         pw.println("Applications Database Info:");
   11742 
   11743         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   11744             ProcessRecord r = procs.get(i);
   11745             if (r.thread != null) {
   11746                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
   11747                 pw.flush();
   11748                 try {
   11749                     TransferPipe tp = new TransferPipe();
   11750                     try {
   11751                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
   11752                         tp.go(fd);
   11753                     } finally {
   11754                         tp.kill();
   11755                     }
   11756                 } catch (IOException e) {
   11757                     pw.println("Failure while dumping the app: " + r);
   11758                     pw.flush();
   11759                 } catch (RemoteException e) {
   11760                     pw.println("Got a RemoteException while dumping the app " + r);
   11761                     pw.flush();
   11762                 }
   11763             }
   11764         }
   11765     }
   11766 
   11767     final static class MemItem {
   11768         final boolean isProc;
   11769         final String label;
   11770         final String shortLabel;
   11771         final long pss;
   11772         final int id;
   11773         final boolean hasActivities;
   11774         ArrayList<MemItem> subitems;
   11775 
   11776         public MemItem(String _label, String _shortLabel, long _pss, int _id,
   11777                 boolean _hasActivities) {
   11778             isProc = true;
   11779             label = _label;
   11780             shortLabel = _shortLabel;
   11781             pss = _pss;
   11782             id = _id;
   11783             hasActivities = _hasActivities;
   11784         }
   11785 
   11786         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
   11787             isProc = false;
   11788             label = _label;
   11789             shortLabel = _shortLabel;
   11790             pss = _pss;
   11791             id = _id;
   11792             hasActivities = false;
   11793         }
   11794     }
   11795 
   11796     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
   11797             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
   11798         if (sort && !isCompact) {
   11799             Collections.sort(items, new Comparator<MemItem>() {
   11800                 @Override
   11801                 public int compare(MemItem lhs, MemItem rhs) {
   11802                     if (lhs.pss < rhs.pss) {
   11803                         return 1;
   11804                     } else if (lhs.pss > rhs.pss) {
   11805                         return -1;
   11806                     }
   11807                     return 0;
   11808                 }
   11809             });
   11810         }
   11811 
   11812         for (int i=0; i<items.size(); i++) {
   11813             MemItem mi = items.get(i);
   11814             if (!isCompact) {
   11815                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
   11816             } else if (mi.isProc) {
   11817                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
   11818                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
   11819                 pw.println(mi.hasActivities ? ",a" : ",e");
   11820             } else {
   11821                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
   11822                 pw.println(mi.pss);
   11823             }
   11824             if (mi.subitems != null) {
   11825                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
   11826                         true, isCompact);
   11827             }
   11828         }
   11829     }
   11830 
   11831     // These are in KB.
   11832     static final long[] DUMP_MEM_BUCKETS = new long[] {
   11833         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
   11834         120*1024, 160*1024, 200*1024,
   11835         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
   11836         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
   11837     };
   11838 
   11839     static final void appendMemBucket(StringBuilder out, long memKB, String label,
   11840             boolean stackLike) {
   11841         int start = label.lastIndexOf('.');
   11842         if (start >= 0) start++;
   11843         else start = 0;
   11844         int end = label.length();
   11845         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
   11846             if (DUMP_MEM_BUCKETS[i] >= memKB) {
   11847                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
   11848                 out.append(bucket);
   11849                 out.append(stackLike ? "MB." : "MB ");
   11850                 out.append(label, start, end);
   11851                 return;
   11852             }
   11853         }
   11854         out.append(memKB/1024);
   11855         out.append(stackLike ? "MB." : "MB ");
   11856         out.append(label, start, end);
   11857     }
   11858 
   11859     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
   11860             ProcessList.NATIVE_ADJ,
   11861             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
   11862             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
   11863             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
   11864             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
   11865             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
   11866     };
   11867     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
   11868             "Native",
   11869             "System", "Persistent", "Foreground",
   11870             "Visible", "Perceptible",
   11871             "Heavy Weight", "Backup",
   11872             "A Services", "Home",
   11873             "Previous", "B Services", "Cached"
   11874     };
   11875     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
   11876             "native",
   11877             "sys", "pers", "fore",
   11878             "vis", "percept",
   11879             "heavy", "backup",
   11880             "servicea", "home",
   11881             "prev", "serviceb", "cached"
   11882     };
   11883 
   11884     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
   11885             long realtime, boolean isCheckinRequest, boolean isCompact) {
   11886         if (isCheckinRequest || isCompact) {
   11887             // short checkin version
   11888             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
   11889         } else {
   11890             pw.println("Applications Memory Usage (kB):");
   11891             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
   11892         }
   11893     }
   11894 
   11895     final void dumpApplicationMemoryUsage(FileDescriptor fd,
   11896             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
   11897         boolean dumpDetails = false;
   11898         boolean dumpFullDetails = false;
   11899         boolean dumpDalvik = false;
   11900         boolean oomOnly = false;
   11901         boolean isCompact = false;
   11902         boolean localOnly = false;
   11903 
   11904         int opti = 0;
   11905         while (opti < args.length) {
   11906             String opt = args[opti];
   11907             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   11908                 break;
   11909             }
   11910             opti++;
   11911             if ("-a".equals(opt)) {
   11912                 dumpDetails = true;
   11913                 dumpFullDetails = true;
   11914                 dumpDalvik = true;
   11915             } else if ("-d".equals(opt)) {
   11916                 dumpDalvik = true;
   11917             } else if ("-c".equals(opt)) {
   11918                 isCompact = true;
   11919             } else if ("--oom".equals(opt)) {
   11920                 oomOnly = true;
   11921             } else if ("--local".equals(opt)) {
   11922                 localOnly = true;
   11923             } else if ("-h".equals(opt)) {
   11924                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
   11925                 pw.println("  -a: include all available information for each process.");
   11926                 pw.println("  -d: include dalvik details when dumping process details.");
   11927                 pw.println("  -c: dump in a compact machine-parseable representation.");
   11928                 pw.println("  --oom: only show processes organized by oom adj.");
   11929                 pw.println("  --local: only collect details locally, don't call process.");
   11930                 pw.println("If [process] is specified it can be the name or ");
   11931                 pw.println("pid of a specific process to dump.");
   11932                 return;
   11933             } else {
   11934                 pw.println("Unknown argument: " + opt + "; use -h for help");
   11935             }
   11936         }
   11937 
   11938         final boolean isCheckinRequest = scanArgs(args, "--checkin");
   11939         long uptime = SystemClock.uptimeMillis();
   11940         long realtime = SystemClock.elapsedRealtime();
   11941         final long[] tmpLong = new long[1];
   11942 
   11943         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
   11944         if (procs == null) {
   11945             // No Java processes.  Maybe they want to print a native process.
   11946             if (args != null && args.length > opti
   11947                     && args[opti].charAt(0) != '-') {
   11948                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
   11949                         = new ArrayList<ProcessCpuTracker.Stats>();
   11950                 updateCpuStatsNow();
   11951                 int findPid = -1;
   11952                 try {
   11953                     findPid = Integer.parseInt(args[opti]);
   11954                 } catch (NumberFormatException e) {
   11955                 }
   11956                 synchronized (mProcessCpuThread) {
   11957                     final int N = mProcessCpuTracker.countStats();
   11958                     for (int i=0; i<N; i++) {
   11959                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   11960                         if (st.pid == findPid || (st.baseName != null
   11961                                 && st.baseName.equals(args[opti]))) {
   11962                             nativeProcs.add(st);
   11963                         }
   11964                     }
   11965                 }
   11966                 if (nativeProcs.size() > 0) {
   11967                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
   11968                             isCompact);
   11969                     Debug.MemoryInfo mi = null;
   11970                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
   11971                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
   11972                         final int pid = r.pid;
   11973                         if (!isCheckinRequest && dumpDetails) {
   11974                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
   11975                         }
   11976                         if (mi == null) {
   11977                             mi = new Debug.MemoryInfo();
   11978                         }
   11979                         if (dumpDetails || (!brief && !oomOnly)) {
   11980                             Debug.getMemoryInfo(pid, mi);
   11981                         } else {
   11982                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   11983                             mi.dalvikPrivateDirty = (int)tmpLong[0];
   11984                         }
   11985                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   11986                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
   11987                         if (isCheckinRequest) {
   11988                             pw.println();
   11989                         }
   11990                     }
   11991                     return;
   11992                 }
   11993             }
   11994             pw.println("No process found for: " + args[opti]);
   11995             return;
   11996         }
   11997 
   11998         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
   11999             dumpDetails = true;
   12000         }
   12001 
   12002         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
   12003 
   12004         String[] innerArgs = new String[args.length-opti];
   12005         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
   12006 
   12007         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
   12008         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
   12009         long nativePss=0, dalvikPss=0, otherPss=0;
   12010         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
   12011 
   12012         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
   12013         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
   12014                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
   12015 
   12016         long totalPss = 0;
   12017         long cachedPss = 0;
   12018 
   12019         Debug.MemoryInfo mi = null;
   12020         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
   12021             final ProcessRecord r = procs.get(i);
   12022             final IApplicationThread thread;
   12023             final int pid;
   12024             final int oomAdj;
   12025             final boolean hasActivities;
   12026             synchronized (this) {
   12027                 thread = r.thread;
   12028                 pid = r.pid;
   12029                 oomAdj = r.getSetAdjWithServices();
   12030                 hasActivities = r.activities.size() > 0;
   12031             }
   12032             if (thread != null) {
   12033                 if (!isCheckinRequest && dumpDetails) {
   12034                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
   12035                 }
   12036                 if (mi == null) {
   12037                     mi = new Debug.MemoryInfo();
   12038                 }
   12039                 if (dumpDetails || (!brief && !oomOnly)) {
   12040                     Debug.getMemoryInfo(pid, mi);
   12041                 } else {
   12042                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
   12043                     mi.dalvikPrivateDirty = (int)tmpLong[0];
   12044                 }
   12045                 if (dumpDetails) {
   12046                     if (localOnly) {
   12047                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
   12048                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
   12049                         if (isCheckinRequest) {
   12050                             pw.println();
   12051                         }
   12052                     } else {
   12053                         try {
   12054                             pw.flush();
   12055                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
   12056                                     dumpDalvik, innerArgs);
   12057                         } catch (RemoteException e) {
   12058                             if (!isCheckinRequest) {
   12059                                 pw.println("Got RemoteException!");
   12060                                 pw.flush();
   12061                             }
   12062                         }
   12063                     }
   12064                 }
   12065 
   12066                 final long myTotalPss = mi.getTotalPss();
   12067                 final long myTotalUss = mi.getTotalUss();
   12068 
   12069                 synchronized (this) {
   12070                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
   12071                         // Record this for posterity if the process has been stable.
   12072                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
   12073                     }
   12074                 }
   12075 
   12076                 if (!isCheckinRequest && mi != null) {
   12077                     totalPss += myTotalPss;
   12078                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
   12079                             (hasActivities ? " / activities)" : ")"),
   12080                             r.processName, myTotalPss, pid, hasActivities);
   12081                     procMems.add(pssItem);
   12082                     procMemsMap.put(pid, pssItem);
   12083 
   12084                     nativePss += mi.nativePss;
   12085                     dalvikPss += mi.dalvikPss;
   12086                     otherPss += mi.otherPss;
   12087                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12088                         long mem = mi.getOtherPss(j);
   12089                         miscPss[j] += mem;
   12090                         otherPss -= mem;
   12091                     }
   12092 
   12093                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
   12094                         cachedPss += myTotalPss;
   12095                     }
   12096 
   12097                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
   12098                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
   12099                                 || oomIndex == (oomPss.length-1)) {
   12100                             oomPss[oomIndex] += myTotalPss;
   12101                             if (oomProcs[oomIndex] == null) {
   12102                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
   12103                             }
   12104                             oomProcs[oomIndex].add(pssItem);
   12105                             break;
   12106                         }
   12107                     }
   12108                 }
   12109             }
   12110         }
   12111 
   12112         if (!isCheckinRequest && procs.size() > 1) {
   12113             // If we are showing aggregations, also look for native processes to
   12114             // include so that our aggregations are more accurate.
   12115             updateCpuStatsNow();
   12116             synchronized (mProcessCpuThread) {
   12117                 final int N = mProcessCpuTracker.countStats();
   12118                 for (int i=0; i<N; i++) {
   12119                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
   12120                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
   12121                         if (mi == null) {
   12122                             mi = new Debug.MemoryInfo();
   12123                         }
   12124                         if (!brief && !oomOnly) {
   12125                             Debug.getMemoryInfo(st.pid, mi);
   12126                         } else {
   12127                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
   12128                             mi.nativePrivateDirty = (int)tmpLong[0];
   12129                         }
   12130 
   12131                         final long myTotalPss = mi.getTotalPss();
   12132                         totalPss += myTotalPss;
   12133 
   12134                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
   12135                                 st.name, myTotalPss, st.pid, false);
   12136                         procMems.add(pssItem);
   12137 
   12138                         nativePss += mi.nativePss;
   12139                         dalvikPss += mi.dalvikPss;
   12140                         otherPss += mi.otherPss;
   12141                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12142                             long mem = mi.getOtherPss(j);
   12143                             miscPss[j] += mem;
   12144                             otherPss -= mem;
   12145                         }
   12146                         oomPss[0] += myTotalPss;
   12147                         if (oomProcs[0] == null) {
   12148                             oomProcs[0] = new ArrayList<MemItem>();
   12149                         }
   12150                         oomProcs[0].add(pssItem);
   12151                     }
   12152                 }
   12153             }
   12154 
   12155             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
   12156 
   12157             catMems.add(new MemItem("Native", "Native", nativePss, -1));
   12158             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
   12159             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
   12160             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
   12161                 String label = Debug.MemoryInfo.getOtherLabel(j);
   12162                 catMems.add(new MemItem(label, label, miscPss[j], j));
   12163             }
   12164 
   12165             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
   12166             for (int j=0; j<oomPss.length; j++) {
   12167                 if (oomPss[j] != 0) {
   12168                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
   12169                             : DUMP_MEM_OOM_LABEL[j];
   12170                     MemItem item = new MemItem(label, label, oomPss[j],
   12171                             DUMP_MEM_OOM_ADJ[j]);
   12172                     item.subitems = oomProcs[j];
   12173                     oomMems.add(item);
   12174                 }
   12175             }
   12176 
   12177             if (!brief && !oomOnly && !isCompact) {
   12178                 pw.println();
   12179                 pw.println("Total PSS by process:");
   12180                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
   12181                 pw.println();
   12182             }
   12183             if (!isCompact) {
   12184                 pw.println("Total PSS by OOM adjustment:");
   12185             }
   12186             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
   12187             if (!brief && !oomOnly) {
   12188                 PrintWriter out = categoryPw != null ? categoryPw : pw;
   12189                 if (!isCompact) {
   12190                     out.println();
   12191                     out.println("Total PSS by category:");
   12192                 }
   12193                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
   12194             }
   12195             if (!isCompact) {
   12196                 pw.println();
   12197             }
   12198             MemInfoReader memInfo = new MemInfoReader();
   12199             memInfo.readMemInfo();
   12200             if (!brief) {
   12201                 if (!isCompact) {
   12202                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
   12203                     pw.println(" kB");
   12204                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
   12205                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
   12206                             pw.print(cachedPss); pw.print(" cached pss + ");
   12207                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
   12208                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
   12209                 } else {
   12210                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
   12211                     pw.print(cachedPss + memInfo.getCachedSizeKb()
   12212                             + memInfo.getFreeSizeKb()); pw.print(",");
   12213                     pw.println(totalPss - cachedPss);
   12214                 }
   12215             }
   12216             if (!isCompact) {
   12217                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
   12218                         + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
   12219                         + memInfo.getSlabSizeKb()); pw.print(" kB (");
   12220                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
   12221                         pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
   12222                         pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
   12223                         pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
   12224                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
   12225                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
   12226                         - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
   12227                         - memInfo.getSlabSizeKb()); pw.println(" kB");
   12228             }
   12229             if (!brief) {
   12230                 if (memInfo.getZramTotalSizeKb() != 0) {
   12231                     if (!isCompact) {
   12232                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
   12233                                 pw.print(" kB physical used for ");
   12234                                 pw.print(memInfo.getSwapTotalSizeKb()
   12235                                         - memInfo.getSwapFreeSizeKb());
   12236                                 pw.print(" kB in swap (");
   12237                                 pw.print(memInfo.getSwapTotalSizeKb());
   12238                                 pw.println(" kB total swap)");
   12239                     } else {
   12240                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
   12241                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
   12242                                 pw.println(memInfo.getSwapFreeSizeKb());
   12243                     }
   12244                 }
   12245                 final int[] SINGLE_LONG_FORMAT = new int[] {
   12246                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
   12247                 };
   12248                 long[] longOut = new long[1];
   12249                 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
   12250                         SINGLE_LONG_FORMAT, null, longOut, null);
   12251                 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12252                 longOut[0] = 0;
   12253                 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
   12254                         SINGLE_LONG_FORMAT, null, longOut, null);
   12255                 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12256                 longOut[0] = 0;
   12257                 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
   12258                         SINGLE_LONG_FORMAT, null, longOut, null);
   12259                 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12260                 longOut[0] = 0;
   12261                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
   12262                         SINGLE_LONG_FORMAT, null, longOut, null);
   12263                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
   12264                 if (!isCompact) {
   12265                     if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
   12266                         pw.print("      KSM: "); pw.print(sharing);
   12267                                 pw.print(" kB saved from shared ");
   12268                                 pw.print(shared); pw.println(" kB");
   12269                         pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
   12270                                 pw.print(voltile); pw.println(" kB volatile");
   12271                     }
   12272                     pw.print("   Tuning: ");
   12273                     pw.print(ActivityManager.staticGetMemoryClass());
   12274                     pw.print(" (large ");
   12275                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12276                     pw.print("), oom ");
   12277                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12278                     pw.print(" kB");
   12279                     pw.print(", restore limit ");
   12280                     pw.print(mProcessList.getCachedRestoreThresholdKb());
   12281                     pw.print(" kB");
   12282                     if (ActivityManager.isLowRamDeviceStatic()) {
   12283                         pw.print(" (low-ram)");
   12284                     }
   12285                     if (ActivityManager.isHighEndGfx()) {
   12286                         pw.print(" (high-end-gfx)");
   12287                     }
   12288                     pw.println();
   12289                 } else {
   12290                     pw.print("ksm,"); pw.print(sharing); pw.print(",");
   12291                     pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
   12292                     pw.println(voltile);
   12293                     pw.print("tuning,");
   12294                     pw.print(ActivityManager.staticGetMemoryClass());
   12295                     pw.print(',');
   12296                     pw.print(ActivityManager.staticGetLargeMemoryClass());
   12297                     pw.print(',');
   12298                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
   12299                     if (ActivityManager.isLowRamDeviceStatic()) {
   12300                         pw.print(",low-ram");
   12301                     }
   12302                     if (ActivityManager.isHighEndGfx()) {
   12303                         pw.print(",high-end-gfx");
   12304                     }
   12305                     pw.println();
   12306                 }
   12307             }
   12308         }
   12309     }
   12310 
   12311     /**
   12312      * Searches array of arguments for the specified string
   12313      * @param args array of argument strings
   12314      * @param value value to search for
   12315      * @return true if the value is contained in the array
   12316      */
   12317     private static boolean scanArgs(String[] args, String value) {
   12318         if (args != null) {
   12319             for (String arg : args) {
   12320                 if (value.equals(arg)) {
   12321                     return true;
   12322                 }
   12323             }
   12324         }
   12325         return false;
   12326     }
   12327 
   12328     private final boolean removeDyingProviderLocked(ProcessRecord proc,
   12329             ContentProviderRecord cpr, boolean always) {
   12330         final boolean inLaunching = mLaunchingProviders.contains(cpr);
   12331 
   12332         if (!inLaunching || always) {
   12333             synchronized (cpr) {
   12334                 cpr.launchingApp = null;
   12335                 cpr.notifyAll();
   12336             }
   12337             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
   12338             String names[] = cpr.info.authority.split(";");
   12339             for (int j = 0; j < names.length; j++) {
   12340                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
   12341             }
   12342         }
   12343 
   12344         for (int i=0; i<cpr.connections.size(); i++) {
   12345             ContentProviderConnection conn = cpr.connections.get(i);
   12346             if (conn.waiting) {
   12347                 // If this connection is waiting for the provider, then we don't
   12348                 // need to mess with its process unless we are always removing
   12349                 // or for some reason the provider is not currently launching.
   12350                 if (inLaunching && !always) {
   12351                     continue;
   12352                 }
   12353             }
   12354             ProcessRecord capp = conn.client;
   12355             conn.dead = true;
   12356             if (conn.stableCount > 0) {
   12357                 if (!capp.persistent && capp.thread != null
   12358                         && capp.pid != 0
   12359                         && capp.pid != MY_PID) {
   12360                     killUnneededProcessLocked(capp, "depends on provider "
   12361                             + cpr.name.flattenToShortString()
   12362                             + " in dying proc " + (proc != null ? proc.processName : "??"));
   12363                 }
   12364             } else if (capp.thread != null && conn.provider.provider != null) {
   12365                 try {
   12366                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
   12367                 } catch (RemoteException e) {
   12368                 }
   12369                 // In the protocol here, we don't expect the client to correctly
   12370                 // clean up this connection, we'll just remove it.
   12371                 cpr.connections.remove(i);
   12372                 conn.client.conProviders.remove(conn);
   12373             }
   12374         }
   12375 
   12376         if (inLaunching && always) {
   12377             mLaunchingProviders.remove(cpr);
   12378         }
   12379         return inLaunching;
   12380     }
   12381 
   12382     /**
   12383      * Main code for cleaning up a process when it has gone away.  This is
   12384      * called both as a result of the process dying, or directly when stopping
   12385      * a process when running in single process mode.
   12386      */
   12387     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
   12388             boolean restarting, boolean allowRestart, int index) {
   12389         if (index >= 0) {
   12390             removeLruProcessLocked(app);
   12391         }
   12392 
   12393         mProcessesToGc.remove(app);
   12394         mPendingPssProcesses.remove(app);
   12395 
   12396         // Dismiss any open dialogs.
   12397         if (app.crashDialog != null && !app.forceCrashReport) {
   12398             app.crashDialog.dismiss();
   12399             app.crashDialog = null;
   12400         }
   12401         if (app.anrDialog != null) {
   12402             app.anrDialog.dismiss();
   12403             app.anrDialog = null;
   12404         }
   12405         if (app.waitDialog != null) {
   12406             app.waitDialog.dismiss();
   12407             app.waitDialog = null;
   12408         }
   12409 
   12410         app.crashing = false;
   12411         app.notResponding = false;
   12412 
   12413         app.resetPackageList(mProcessStats);
   12414         app.unlinkDeathRecipient();
   12415         app.makeInactive(mProcessStats);
   12416         app.forcingToForeground = null;
   12417         app.foregroundServices = false;
   12418         app.foregroundActivities = false;
   12419         app.hasShownUi = false;
   12420         app.hasAboveClient = false;
   12421 
   12422         mServices.killServicesLocked(app, allowRestart);
   12423 
   12424         boolean restart = false;
   12425 
   12426         // Remove published content providers.
   12427         for (int i=app.pubProviders.size()-1; i>=0; i--) {
   12428             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
   12429             final boolean always = app.bad || !allowRestart;
   12430             if (removeDyingProviderLocked(app, cpr, always) || always) {
   12431                 // We left the provider in the launching list, need to
   12432                 // restart it.
   12433                 restart = true;
   12434             }
   12435 
   12436             cpr.provider = null;
   12437             cpr.proc = null;
   12438         }
   12439         app.pubProviders.clear();
   12440 
   12441         // Take care of any launching providers waiting for this process.
   12442         if (checkAppInLaunchingProvidersLocked(app, false)) {
   12443             restart = true;
   12444         }
   12445 
   12446         // Unregister from connected content providers.
   12447         if (!app.conProviders.isEmpty()) {
   12448             for (int i=0; i<app.conProviders.size(); i++) {
   12449                 ContentProviderConnection conn = app.conProviders.get(i);
   12450                 conn.provider.connections.remove(conn);
   12451             }
   12452             app.conProviders.clear();
   12453         }
   12454 
   12455         // At this point there may be remaining entries in mLaunchingProviders
   12456         // where we were the only one waiting, so they are no longer of use.
   12457         // Look for these and clean up if found.
   12458         // XXX Commented out for now.  Trying to figure out a way to reproduce
   12459         // the actual situation to identify what is actually going on.
   12460         if (false) {
   12461             for (int i=0; i<mLaunchingProviders.size(); i++) {
   12462                 ContentProviderRecord cpr = (ContentProviderRecord)
   12463                         mLaunchingProviders.get(i);
   12464                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
   12465                     synchronized (cpr) {
   12466                         cpr.launchingApp = null;
   12467                         cpr.notifyAll();
   12468                     }
   12469                 }
   12470             }
   12471         }
   12472 
   12473         skipCurrentReceiverLocked(app);
   12474 
   12475         // Unregister any receivers.
   12476         for (int i=app.receivers.size()-1; i>=0; i--) {
   12477             removeReceiverLocked(app.receivers.valueAt(i));
   12478         }
   12479         app.receivers.clear();
   12480 
   12481         // If the app is undergoing backup, tell the backup manager about it
   12482         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
   12483             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
   12484                     + mBackupTarget.appInfo + " died during backup");
   12485             try {
   12486                 IBackupManager bm = IBackupManager.Stub.asInterface(
   12487                         ServiceManager.getService(Context.BACKUP_SERVICE));
   12488                 bm.agentDisconnected(app.info.packageName);
   12489             } catch (RemoteException e) {
   12490                 // can't happen; backup manager is local
   12491             }
   12492         }
   12493 
   12494         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
   12495             ProcessChangeItem item = mPendingProcessChanges.get(i);
   12496             if (item.pid == app.pid) {
   12497                 mPendingProcessChanges.remove(i);
   12498                 mAvailProcessChanges.add(item);
   12499             }
   12500         }
   12501         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
   12502 
   12503         // If the caller is restarting this app, then leave it in its
   12504         // current lists and let the caller take care of it.
   12505         if (restarting) {
   12506             return;
   12507         }
   12508 
   12509         if (!app.persistent || app.isolated) {
   12510             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
   12511                     "Removing non-persistent process during cleanup: " + app);
   12512             mProcessNames.remove(app.processName, app.uid);
   12513             mIsolatedProcesses.remove(app.uid);
   12514             if (mHeavyWeightProcess == app) {
   12515                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
   12516                         mHeavyWeightProcess.userId, 0));
   12517                 mHeavyWeightProcess = null;
   12518             }
   12519         } else if (!app.removed) {
   12520             // This app is persistent, so we need to keep its record around.
   12521             // If it is not already on the pending app list, add it there
   12522             // and start a new process for it.
   12523             if (mPersistentStartingProcesses.indexOf(app) < 0) {
   12524                 mPersistentStartingProcesses.add(app);
   12525                 restart = true;
   12526             }
   12527         }
   12528         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
   12529                 "Clean-up removing on hold: " + app);
   12530         mProcessesOnHold.remove(app);
   12531 
   12532         if (app == mHomeProcess) {
   12533             mHomeProcess = null;
   12534         }
   12535         if (app == mPreviousProcess) {
   12536             mPreviousProcess = null;
   12537         }
   12538 
   12539         if (restart && !app.isolated) {
   12540             // We have components that still need to be running in the
   12541             // process, so re-launch it.
   12542             mProcessNames.put(app.processName, app.uid, app);
   12543             startProcessLocked(app, "restart", app.processName);
   12544         } else if (app.pid > 0 && app.pid != MY_PID) {
   12545             // Goodbye!
   12546             synchronized (mPidsSelfLocked) {
   12547                 mPidsSelfLocked.remove(app.pid);
   12548                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
   12549             }
   12550             app.setPid(0);
   12551         }
   12552     }
   12553 
   12554     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
   12555         // Look through the content providers we are waiting to have launched,
   12556         // and if any run in this process then either schedule a restart of
   12557         // the process or kill the client waiting for it if this process has
   12558         // gone bad.
   12559         int NL = mLaunchingProviders.size();
   12560         boolean restart = false;
   12561         for (int i=0; i<NL; i++) {
   12562             ContentProviderRecord cpr = mLaunchingProviders.get(i);
   12563             if (cpr.launchingApp == app) {
   12564                 if (!alwaysBad && !app.bad) {
   12565                     restart = true;
   12566                 } else {
   12567                     removeDyingProviderLocked(app, cpr, true);
   12568                     // cpr should have been removed from mLaunchingProviders
   12569                     NL = mLaunchingProviders.size();
   12570                     i--;
   12571                 }
   12572             }
   12573         }
   12574         return restart;
   12575     }
   12576 
   12577     // =========================================================
   12578     // SERVICES
   12579     // =========================================================
   12580 
   12581     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
   12582             int flags) {
   12583         enforceNotIsolatedCaller("getServices");
   12584         synchronized (this) {
   12585             return mServices.getRunningServiceInfoLocked(maxNum, flags);
   12586         }
   12587     }
   12588 
   12589     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
   12590         enforceNotIsolatedCaller("getRunningServiceControlPanel");
   12591         synchronized (this) {
   12592             return mServices.getRunningServiceControlPanelLocked(name);
   12593         }
   12594     }
   12595 
   12596     public ComponentName startService(IApplicationThread caller, Intent service,
   12597             String resolvedType, int userId) {
   12598         enforceNotIsolatedCaller("startService");
   12599         // Refuse possible leaked file descriptors
   12600         if (service != null && service.hasFileDescriptors() == true) {
   12601             throw new IllegalArgumentException("File descriptors passed in Intent");
   12602         }
   12603 
   12604         if (DEBUG_SERVICE)
   12605             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
   12606         synchronized(this) {
   12607             final int callingPid = Binder.getCallingPid();
   12608             final int callingUid = Binder.getCallingUid();
   12609             final long origId = Binder.clearCallingIdentity();
   12610             ComponentName res = mServices.startServiceLocked(caller, service,
   12611                     resolvedType, callingPid, callingUid, userId);
   12612             Binder.restoreCallingIdentity(origId);
   12613             return res;
   12614         }
   12615     }
   12616 
   12617     ComponentName startServiceInPackage(int uid,
   12618             Intent service, String resolvedType, int userId) {
   12619         synchronized(this) {
   12620             if (DEBUG_SERVICE)
   12621                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
   12622             final long origId = Binder.clearCallingIdentity();
   12623             ComponentName res = mServices.startServiceLocked(null, service,
   12624                     resolvedType, -1, uid, userId);
   12625             Binder.restoreCallingIdentity(origId);
   12626             return res;
   12627         }
   12628     }
   12629 
   12630     public int stopService(IApplicationThread caller, Intent service,
   12631             String resolvedType, int userId) {
   12632         enforceNotIsolatedCaller("stopService");
   12633         // Refuse possible leaked file descriptors
   12634         if (service != null && service.hasFileDescriptors() == true) {
   12635             throw new IllegalArgumentException("File descriptors passed in Intent");
   12636         }
   12637 
   12638         synchronized(this) {
   12639             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
   12640         }
   12641     }
   12642 
   12643     public IBinder peekService(Intent service, String resolvedType) {
   12644         enforceNotIsolatedCaller("peekService");
   12645         // Refuse possible leaked file descriptors
   12646         if (service != null && service.hasFileDescriptors() == true) {
   12647             throw new IllegalArgumentException("File descriptors passed in Intent");
   12648         }
   12649         synchronized(this) {
   12650             return mServices.peekServiceLocked(service, resolvedType);
   12651         }
   12652     }
   12653 
   12654     public boolean stopServiceToken(ComponentName className, IBinder token,
   12655             int startId) {
   12656         synchronized(this) {
   12657             return mServices.stopServiceTokenLocked(className, token, startId);
   12658         }
   12659     }
   12660 
   12661     public void setServiceForeground(ComponentName className, IBinder token,
   12662             int id, Notification notification, boolean removeNotification) {
   12663         synchronized(this) {
   12664             mServices.setServiceForegroundLocked(className, token, id, notification,
   12665                     removeNotification);
   12666         }
   12667     }
   12668 
   12669     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
   12670             boolean requireFull, String name, String callerPackage) {
   12671         final int callingUserId = UserHandle.getUserId(callingUid);
   12672         if (callingUserId != userId) {
   12673             if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   12674                 if ((requireFull || checkComponentPermission(
   12675                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12676                         callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
   12677                         && checkComponentPermission(
   12678                                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   12679                                 callingPid, callingUid, -1, true)
   12680                                 != PackageManager.PERMISSION_GRANTED) {
   12681                     if (userId == UserHandle.USER_CURRENT_OR_SELF) {
   12682                         // In this case, they would like to just execute as their
   12683                         // owner user instead of failing.
   12684                         userId = callingUserId;
   12685                     } else {
   12686                         StringBuilder builder = new StringBuilder(128);
   12687                         builder.append("Permission Denial: ");
   12688                         builder.append(name);
   12689                         if (callerPackage != null) {
   12690                             builder.append(" from ");
   12691                             builder.append(callerPackage);
   12692                         }
   12693                         builder.append(" asks to run as user ");
   12694                         builder.append(userId);
   12695                         builder.append(" but is calling from user ");
   12696                         builder.append(UserHandle.getUserId(callingUid));
   12697                         builder.append("; this requires ");
   12698                         builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
   12699                         if (!requireFull) {
   12700                             builder.append(" or ");
   12701                             builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
   12702                         }
   12703                         String msg = builder.toString();
   12704                         Slog.w(TAG, msg);
   12705                         throw new SecurityException(msg);
   12706                     }
   12707                 }
   12708             }
   12709             if (userId == UserHandle.USER_CURRENT
   12710                     || userId == UserHandle.USER_CURRENT_OR_SELF) {
   12711                 // Note that we may be accessing this outside of a lock...
   12712                 // shouldn't be a big deal, if this is being called outside
   12713                 // of a locked context there is intrinsically a race with
   12714                 // the value the caller will receive and someone else changing it.
   12715                 userId = mCurrentUserId;
   12716             }
   12717             if (!allowAll && userId < 0) {
   12718                 throw new IllegalArgumentException(
   12719                         "Call does not support special user #" + userId);
   12720             }
   12721         }
   12722         return userId;
   12723     }
   12724 
   12725     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
   12726             String className, int flags) {
   12727         boolean result = false;
   12728         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
   12729             if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
   12730                 if (ActivityManager.checkUidPermission(
   12731                         android.Manifest.permission.INTERACT_ACROSS_USERS,
   12732                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
   12733                     ComponentName comp = new ComponentName(aInfo.packageName, className);
   12734                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
   12735                             + " requests FLAG_SINGLE_USER, but app does not hold "
   12736                             + android.Manifest.permission.INTERACT_ACROSS_USERS;
   12737                     Slog.w(TAG, msg);
   12738                     throw new SecurityException(msg);
   12739                 }
   12740                 result = true;
   12741             }
   12742         } else if (componentProcessName == aInfo.packageName) {
   12743             result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
   12744         } else if ("system".equals(componentProcessName)) {
   12745             result = true;
   12746         }
   12747         if (DEBUG_MU) {
   12748             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
   12749                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
   12750         }
   12751         return result;
   12752     }
   12753 
   12754     public int bindService(IApplicationThread caller, IBinder token,
   12755             Intent service, String resolvedType,
   12756             IServiceConnection connection, int flags, int userId) {
   12757         enforceNotIsolatedCaller("bindService");
   12758         // Refuse possible leaked file descriptors
   12759         if (service != null && service.hasFileDescriptors() == true) {
   12760             throw new IllegalArgumentException("File descriptors passed in Intent");
   12761         }
   12762 
   12763         synchronized(this) {
   12764             return mServices.bindServiceLocked(caller, token, service, resolvedType,
   12765                     connection, flags, userId);
   12766         }
   12767     }
   12768 
   12769     public boolean unbindService(IServiceConnection connection) {
   12770         synchronized (this) {
   12771             return mServices.unbindServiceLocked(connection);
   12772         }
   12773     }
   12774 
   12775     public void publishService(IBinder token, Intent intent, IBinder service) {
   12776         // Refuse possible leaked file descriptors
   12777         if (intent != null && intent.hasFileDescriptors() == true) {
   12778             throw new IllegalArgumentException("File descriptors passed in Intent");
   12779         }
   12780 
   12781         synchronized(this) {
   12782             if (!(token instanceof ServiceRecord)) {
   12783                 throw new IllegalArgumentException("Invalid service token");
   12784             }
   12785             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   12786         }
   12787     }
   12788 
   12789     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
   12790         // Refuse possible leaked file descriptors
   12791         if (intent != null && intent.hasFileDescriptors() == true) {
   12792             throw new IllegalArgumentException("File descriptors passed in Intent");
   12793         }
   12794 
   12795         synchronized(this) {
   12796             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
   12797         }
   12798     }
   12799 
   12800     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
   12801         synchronized(this) {
   12802             if (!(token instanceof ServiceRecord)) {
   12803                 throw new IllegalArgumentException("Invalid service token");
   12804             }
   12805             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
   12806         }
   12807     }
   12808 
   12809     // =========================================================
   12810     // BACKUP AND RESTORE
   12811     // =========================================================
   12812 
   12813     // Cause the target app to be launched if necessary and its backup agent
   12814     // instantiated.  The backup agent will invoke backupAgentCreated() on the
   12815     // activity manager to announce its creation.
   12816     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
   12817         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
   12818         enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
   12819 
   12820         synchronized(this) {
   12821             // !!! TODO: currently no check here that we're already bound
   12822             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
   12823             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   12824             synchronized (stats) {
   12825                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
   12826             }
   12827 
   12828             // Backup agent is now in use, its package can't be stopped.
   12829             try {
   12830                 AppGlobals.getPackageManager().setPackageStoppedState(
   12831                         app.packageName, false, UserHandle.getUserId(app.uid));
   12832             } catch (RemoteException e) {
   12833             } catch (IllegalArgumentException e) {
   12834                 Slog.w(TAG, "Failed trying to unstop package "
   12835                         + app.packageName + ": " + e);
   12836             }
   12837 
   12838             BackupRecord r = new BackupRecord(ss, app, backupMode);
   12839             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
   12840                     ? new ComponentName(app.packageName, app.backupAgentName)
   12841                     : new ComponentName("android", "FullBackupAgent");
   12842             // startProcessLocked() returns existing proc's record if it's already running
   12843             ProcessRecord proc = startProcessLocked(app.processName, app,
   12844                     false, 0, "backup", hostingName, false, false, false);
   12845             if (proc == null) {
   12846                 Slog.e(TAG, "Unable to start backup agent process " + r);
   12847                 return false;
   12848             }
   12849 
   12850             r.app = proc;
   12851             mBackupTarget = r;
   12852             mBackupAppName = app.packageName;
   12853 
   12854             // Try not to kill the process during backup
   12855             updateOomAdjLocked(proc);
   12856 
   12857             // If the process is already attached, schedule the creation of the backup agent now.
   12858             // If it is not yet live, this will be done when it attaches to the framework.
   12859             if (proc.thread != null) {
   12860                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
   12861                 try {
   12862                     proc.thread.scheduleCreateBackupAgent(app,
   12863                             compatibilityInfoForPackageLocked(app), backupMode);
   12864                 } catch (RemoteException e) {
   12865                     // Will time out on the backup manager side
   12866                 }
   12867             } else {
   12868                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
   12869             }
   12870             // Invariants: at this point, the target app process exists and the application
   12871             // is either already running or in the process of coming up.  mBackupTarget and
   12872             // mBackupAppName describe the app, so that when it binds back to the AM we
   12873             // know that it's scheduled for a backup-agent operation.
   12874         }
   12875 
   12876         return true;
   12877     }
   12878 
   12879     @Override
   12880     public void clearPendingBackup() {
   12881         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
   12882         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
   12883 
   12884         synchronized (this) {
   12885             mBackupTarget = null;
   12886             mBackupAppName = null;
   12887         }
   12888     }
   12889 
   12890     // A backup agent has just come up
   12891     public void backupAgentCreated(String agentPackageName, IBinder agent) {
   12892         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
   12893                 + " = " + agent);
   12894 
   12895         synchronized(this) {
   12896             if (!agentPackageName.equals(mBackupAppName)) {
   12897                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
   12898                 return;
   12899             }
   12900         }
   12901 
   12902         long oldIdent = Binder.clearCallingIdentity();
   12903         try {
   12904             IBackupManager bm = IBackupManager.Stub.asInterface(
   12905                     ServiceManager.getService(Context.BACKUP_SERVICE));
   12906             bm.agentConnected(agentPackageName, agent);
   12907         } catch (RemoteException e) {
   12908             // can't happen; the backup manager service is local
   12909         } catch (Exception e) {
   12910             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
   12911             e.printStackTrace();
   12912         } finally {
   12913             Binder.restoreCallingIdentity(oldIdent);
   12914         }
   12915     }
   12916 
   12917     // done with this agent
   12918     public void unbindBackupAgent(ApplicationInfo appInfo) {
   12919         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
   12920         if (appInfo == null) {
   12921             Slog.w(TAG, "unbind backup agent for null app");
   12922             return;
   12923         }
   12924 
   12925         synchronized(this) {
   12926             try {
   12927                 if (mBackupAppName == null) {
   12928                     Slog.w(TAG, "Unbinding backup agent with no active backup");
   12929                     return;
   12930                 }
   12931 
   12932                 if (!mBackupAppName.equals(appInfo.packageName)) {
   12933                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
   12934                     return;
   12935                 }
   12936 
   12937                 // Not backing this app up any more; reset its OOM adjustment
   12938                 final ProcessRecord proc = mBackupTarget.app;
   12939                 updateOomAdjLocked(proc);
   12940 
   12941                 // If the app crashed during backup, 'thread' will be null here
   12942                 if (proc.thread != null) {
   12943                     try {
   12944                         proc.thread.scheduleDestroyBackupAgent(appInfo,
   12945                                 compatibilityInfoForPackageLocked(appInfo));
   12946                     } catch (Exception e) {
   12947                         Slog.e(TAG, "Exception when unbinding backup agent:");
   12948                         e.printStackTrace();
   12949                     }
   12950                 }
   12951             } finally {
   12952                 mBackupTarget = null;
   12953                 mBackupAppName = null;
   12954             }
   12955         }
   12956     }
   12957     // =========================================================
   12958     // BROADCASTS
   12959     // =========================================================
   12960 
   12961     private final List getStickiesLocked(String action, IntentFilter filter,
   12962             List cur, int userId) {
   12963         final ContentResolver resolver = mContext.getContentResolver();
   12964         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   12965         if (stickies == null) {
   12966             return cur;
   12967         }
   12968         final ArrayList<Intent> list = stickies.get(action);
   12969         if (list == null) {
   12970             return cur;
   12971         }
   12972         int N = list.size();
   12973         for (int i=0; i<N; i++) {
   12974             Intent intent = list.get(i);
   12975             if (filter.match(resolver, intent, true, TAG) >= 0) {
   12976                 if (cur == null) {
   12977                     cur = new ArrayList<Intent>();
   12978                 }
   12979                 cur.add(intent);
   12980             }
   12981         }
   12982         return cur;
   12983     }
   12984 
   12985     boolean isPendingBroadcastProcessLocked(int pid) {
   12986         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
   12987                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
   12988     }
   12989 
   12990     void skipPendingBroadcastLocked(int pid) {
   12991             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
   12992             for (BroadcastQueue queue : mBroadcastQueues) {
   12993                 queue.skipPendingBroadcastLocked(pid);
   12994             }
   12995     }
   12996 
   12997     // The app just attached; send any pending broadcasts that it should receive
   12998     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
   12999         boolean didSomething = false;
   13000         for (BroadcastQueue queue : mBroadcastQueues) {
   13001             didSomething |= queue.sendPendingBroadcastsLocked(app);
   13002         }
   13003         return didSomething;
   13004     }
   13005 
   13006     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
   13007             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
   13008         enforceNotIsolatedCaller("registerReceiver");
   13009         int callingUid;
   13010         int callingPid;
   13011         synchronized(this) {
   13012             ProcessRecord callerApp = null;
   13013             if (caller != null) {
   13014                 callerApp = getRecordForAppLocked(caller);
   13015                 if (callerApp == null) {
   13016                     throw new SecurityException(
   13017                             "Unable to find app for caller " + caller
   13018                             + " (pid=" + Binder.getCallingPid()
   13019                             + ") when registering receiver " + receiver);
   13020                 }
   13021                 if (callerApp.info.uid != Process.SYSTEM_UID &&
   13022                         !callerApp.pkgList.containsKey(callerPackage) &&
   13023                         !"android".equals(callerPackage)) {
   13024                     throw new SecurityException("Given caller package " + callerPackage
   13025                             + " is not running in process " + callerApp);
   13026                 }
   13027                 callingUid = callerApp.info.uid;
   13028                 callingPid = callerApp.pid;
   13029             } else {
   13030                 callerPackage = null;
   13031                 callingUid = Binder.getCallingUid();
   13032                 callingPid = Binder.getCallingPid();
   13033             }
   13034 
   13035             userId = this.handleIncomingUser(callingPid, callingUid, userId,
   13036                     true, true, "registerReceiver", callerPackage);
   13037 
   13038             List allSticky = null;
   13039 
   13040             // Look for any matching sticky broadcasts...
   13041             Iterator actions = filter.actionsIterator();
   13042             if (actions != null) {
   13043                 while (actions.hasNext()) {
   13044                     String action = (String)actions.next();
   13045                     allSticky = getStickiesLocked(action, filter, allSticky,
   13046                             UserHandle.USER_ALL);
   13047                     allSticky = getStickiesLocked(action, filter, allSticky,
   13048                             UserHandle.getUserId(callingUid));
   13049                 }
   13050             } else {
   13051                 allSticky = getStickiesLocked(null, filter, allSticky,
   13052                         UserHandle.USER_ALL);
   13053                 allSticky = getStickiesLocked(null, filter, allSticky,
   13054                         UserHandle.getUserId(callingUid));
   13055             }
   13056 
   13057             // The first sticky in the list is returned directly back to
   13058             // the client.
   13059             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
   13060 
   13061             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
   13062                     + ": " + sticky);
   13063 
   13064             if (receiver == null) {
   13065                 return sticky;
   13066             }
   13067 
   13068             ReceiverList rl
   13069                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
   13070             if (rl == null) {
   13071                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
   13072                         userId, receiver);
   13073                 if (rl.app != null) {
   13074                     rl.app.receivers.add(rl);
   13075                 } else {
   13076                     try {
   13077                         receiver.asBinder().linkToDeath(rl, 0);
   13078                     } catch (RemoteException e) {
   13079                         return sticky;
   13080                     }
   13081                     rl.linkedToDeath = true;
   13082                 }
   13083                 mRegisteredReceivers.put(receiver.asBinder(), rl);
   13084             } else if (rl.uid != callingUid) {
   13085                 throw new IllegalArgumentException(
   13086                         "Receiver requested to register for uid " + callingUid
   13087                         + " was previously registered for uid " + rl.uid);
   13088             } else if (rl.pid != callingPid) {
   13089                 throw new IllegalArgumentException(
   13090                         "Receiver requested to register for pid " + callingPid
   13091                         + " was previously registered for pid " + rl.pid);
   13092             } else if (rl.userId != userId) {
   13093                 throw new IllegalArgumentException(
   13094                         "Receiver requested to register for user " + userId
   13095                         + " was previously registered for user " + rl.userId);
   13096             }
   13097             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
   13098                     permission, callingUid, userId);
   13099             rl.add(bf);
   13100             if (!bf.debugCheck()) {
   13101                 Slog.w(TAG, "==> For Dynamic broadast");
   13102             }
   13103             mReceiverResolver.addFilter(bf);
   13104 
   13105             // Enqueue broadcasts for all existing stickies that match
   13106             // this filter.
   13107             if (allSticky != null) {
   13108                 ArrayList receivers = new ArrayList();
   13109                 receivers.add(bf);
   13110 
   13111                 int N = allSticky.size();
   13112                 for (int i=0; i<N; i++) {
   13113                     Intent intent = (Intent)allSticky.get(i);
   13114                     BroadcastQueue queue = broadcastQueueForIntent(intent);
   13115                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
   13116                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
   13117                             null, null, false, true, true, -1);
   13118                     queue.enqueueParallelBroadcastLocked(r);
   13119                     queue.scheduleBroadcastsLocked();
   13120                 }
   13121             }
   13122 
   13123             return sticky;
   13124         }
   13125     }
   13126 
   13127     public void unregisterReceiver(IIntentReceiver receiver) {
   13128         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
   13129 
   13130         final long origId = Binder.clearCallingIdentity();
   13131         try {
   13132             boolean doTrim = false;
   13133 
   13134             synchronized(this) {
   13135                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
   13136                 if (rl != null) {
   13137                     if (rl.curBroadcast != null) {
   13138                         BroadcastRecord r = rl.curBroadcast;
   13139                         final boolean doNext = finishReceiverLocked(
   13140                                 receiver.asBinder(), r.resultCode, r.resultData,
   13141                                 r.resultExtras, r.resultAbort);
   13142                         if (doNext) {
   13143                             doTrim = true;
   13144                             r.queue.processNextBroadcast(false);
   13145                         }
   13146                     }
   13147 
   13148                     if (rl.app != null) {
   13149                         rl.app.receivers.remove(rl);
   13150                     }
   13151                     removeReceiverLocked(rl);
   13152                     if (rl.linkedToDeath) {
   13153                         rl.linkedToDeath = false;
   13154                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
   13155                     }
   13156                 }
   13157             }
   13158 
   13159             // If we actually concluded any broadcasts, we might now be able
   13160             // to trim the recipients' apps from our working set
   13161             if (doTrim) {
   13162                 trimApplications();
   13163                 return;
   13164             }
   13165 
   13166         } finally {
   13167             Binder.restoreCallingIdentity(origId);
   13168         }
   13169     }
   13170 
   13171     void removeReceiverLocked(ReceiverList rl) {
   13172         mRegisteredReceivers.remove(rl.receiver.asBinder());
   13173         int N = rl.size();
   13174         for (int i=0; i<N; i++) {
   13175             mReceiverResolver.removeFilter(rl.get(i));
   13176         }
   13177     }
   13178 
   13179     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
   13180         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   13181             ProcessRecord r = mLruProcesses.get(i);
   13182             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
   13183                 try {
   13184                     r.thread.dispatchPackageBroadcast(cmd, packages);
   13185                 } catch (RemoteException ex) {
   13186                 }
   13187             }
   13188         }
   13189     }
   13190 
   13191     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
   13192             int[] users) {
   13193         List<ResolveInfo> receivers = null;
   13194         try {
   13195             HashSet<ComponentName> singleUserReceivers = null;
   13196             boolean scannedFirstReceivers = false;
   13197             for (int user : users) {
   13198                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
   13199                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
   13200                 if (user != 0 && newReceivers != null) {
   13201                     // If this is not the primary user, we need to check for
   13202                     // any receivers that should be filtered out.
   13203                     for (int i=0; i<newReceivers.size(); i++) {
   13204                         ResolveInfo ri = newReceivers.get(i);
   13205                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
   13206                             newReceivers.remove(i);
   13207                             i--;
   13208                         }
   13209                     }
   13210                 }
   13211                 if (newReceivers != null && newReceivers.size() == 0) {
   13212                     newReceivers = null;
   13213                 }
   13214                 if (receivers == null) {
   13215                     receivers = newReceivers;
   13216                 } else if (newReceivers != null) {
   13217                     // We need to concatenate the additional receivers
   13218                     // found with what we have do far.  This would be easy,
   13219                     // but we also need to de-dup any receivers that are
   13220                     // singleUser.
   13221                     if (!scannedFirstReceivers) {
   13222                         // Collect any single user receivers we had already retrieved.
   13223                         scannedFirstReceivers = true;
   13224                         for (int i=0; i<receivers.size(); i++) {
   13225                             ResolveInfo ri = receivers.get(i);
   13226                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   13227                                 ComponentName cn = new ComponentName(
   13228                                         ri.activityInfo.packageName, ri.activityInfo.name);
   13229                                 if (singleUserReceivers == null) {
   13230                                     singleUserReceivers = new HashSet<ComponentName>();
   13231                                 }
   13232                                 singleUserReceivers.add(cn);
   13233                             }
   13234                         }
   13235                     }
   13236                     // Add the new results to the existing results, tracking
   13237                     // and de-dupping single user receivers.
   13238                     for (int i=0; i<newReceivers.size(); i++) {
   13239                         ResolveInfo ri = newReceivers.get(i);
   13240                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
   13241                             ComponentName cn = new ComponentName(
   13242                                     ri.activityInfo.packageName, ri.activityInfo.name);
   13243                             if (singleUserReceivers == null) {
   13244                                 singleUserReceivers = new HashSet<ComponentName>();
   13245                             }
   13246                             if (!singleUserReceivers.contains(cn)) {
   13247                                 singleUserReceivers.add(cn);
   13248                                 receivers.add(ri);
   13249                             }
   13250                         } else {
   13251                             receivers.add(ri);
   13252                         }
   13253                     }
   13254                 }
   13255             }
   13256         } catch (RemoteException ex) {
   13257             // pm is in same process, this will never happen.
   13258         }
   13259         return receivers;
   13260     }
   13261 
   13262     private final int broadcastIntentLocked(ProcessRecord callerApp,
   13263             String callerPackage, Intent intent, String resolvedType,
   13264             IIntentReceiver resultTo, int resultCode, String resultData,
   13265             Bundle map, String requiredPermission, int appOp,
   13266             boolean ordered, boolean sticky, int callingPid, int callingUid,
   13267             int userId) {
   13268         intent = new Intent(intent);
   13269 
   13270         // By default broadcasts do not go to stopped apps.
   13271         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
   13272 
   13273         if (DEBUG_BROADCAST_LIGHT) Slog.v(
   13274             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
   13275             + " ordered=" + ordered + " userid=" + userId);
   13276         if ((resultTo != null) && !ordered) {
   13277             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
   13278         }
   13279 
   13280         userId = handleIncomingUser(callingPid, callingUid, userId,
   13281                 true, false, "broadcast", callerPackage);
   13282 
   13283         // Make sure that the user who is receiving this broadcast is started.
   13284         // If not, we will just skip it.
   13285         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
   13286             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
   13287                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
   13288                 Slog.w(TAG, "Skipping broadcast of " + intent
   13289                         + ": user " + userId + " is stopped");
   13290                 return ActivityManager.BROADCAST_SUCCESS;
   13291             }
   13292         }
   13293 
   13294         /*
   13295          * Prevent non-system code (defined here to be non-persistent
   13296          * processes) from sending protected broadcasts.
   13297          */
   13298         int callingAppId = UserHandle.getAppId(callingUid);
   13299         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
   13300             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
   13301             callingUid == 0) {
   13302             // Always okay.
   13303         } else if (callerApp == null || !callerApp.persistent) {
   13304             try {
   13305                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
   13306                         intent.getAction())) {
   13307                     String msg = "Permission Denial: not allowed to send broadcast "
   13308                             + intent.getAction() + " from pid="
   13309                             + callingPid + ", uid=" + callingUid;
   13310                     Slog.w(TAG, msg);
   13311                     throw new SecurityException(msg);
   13312                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
   13313                     // Special case for compatibility: we don't want apps to send this,
   13314                     // but historically it has not been protected and apps may be using it
   13315                     // to poke their own app widget.  So, instead of making it protected,
   13316                     // just limit it to the caller.
   13317                     if (callerApp == null) {
   13318                         String msg = "Permission Denial: not allowed to send broadcast "
   13319                                 + intent.getAction() + " from unknown caller.";
   13320                         Slog.w(TAG, msg);
   13321                         throw new SecurityException(msg);
   13322                     } else if (intent.getComponent() != null) {
   13323                         // They are good enough to send to an explicit component...  verify
   13324                         // it is being sent to the calling app.
   13325                         if (!intent.getComponent().getPackageName().equals(
   13326                                 callerApp.info.packageName)) {
   13327                             String msg = "Permission Denial: not allowed to send broadcast "
   13328                                     + intent.getAction() + " to "
   13329                                     + intent.getComponent().getPackageName() + " from "
   13330                                     + callerApp.info.packageName;
   13331                             Slog.w(TAG, msg);
   13332                             throw new SecurityException(msg);
   13333                         }
   13334                     } else {
   13335                         // Limit broadcast to their own package.
   13336                         intent.setPackage(callerApp.info.packageName);
   13337                     }
   13338                 }
   13339             } catch (RemoteException e) {
   13340                 Slog.w(TAG, "Remote exception", e);
   13341                 return ActivityManager.BROADCAST_SUCCESS;
   13342             }
   13343         }
   13344 
   13345         // Handle special intents: if this broadcast is from the package
   13346         // manager about a package being removed, we need to remove all of
   13347         // its activities from the history stack.
   13348         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
   13349                 intent.getAction());
   13350         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
   13351                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
   13352                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
   13353                 || uidRemoved) {
   13354             if (checkComponentPermission(
   13355                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
   13356                     callingPid, callingUid, -1, true)
   13357                     == PackageManager.PERMISSION_GRANTED) {
   13358                 if (uidRemoved) {
   13359                     final Bundle intentExtras = intent.getExtras();
   13360                     final int uid = intentExtras != null
   13361                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
   13362                     if (uid >= 0) {
   13363                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
   13364                         synchronized (bs) {
   13365                             bs.removeUidStatsLocked(uid);
   13366                         }
   13367                         mAppOpsService.uidRemoved(uid);
   13368                     }
   13369                 } else {
   13370                     // If resources are unavailable just force stop all
   13371                     // those packages and flush the attribute cache as well.
   13372                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
   13373                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13374                         if (list != null && (list.length > 0)) {
   13375                             for (String pkg : list) {
   13376                                 forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
   13377                                         "storage unmount");
   13378                             }
   13379                             sendPackageBroadcastLocked(
   13380                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
   13381                         }
   13382                     } else {
   13383                         Uri data = intent.getData();
   13384                         String ssp;
   13385                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13386                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
   13387                                     intent.getAction());
   13388                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
   13389                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
   13390                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
   13391                                         false, userId, removed ? "pkg removed" : "pkg changed");
   13392                             }
   13393                             if (removed) {
   13394                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
   13395                                         new String[] {ssp}, userId);
   13396                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
   13397                                     mAppOpsService.packageRemoved(
   13398                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
   13399 
   13400                                     // Remove all permissions granted from/to this package
   13401                                     removeUriPermissionsForPackageLocked(ssp, userId, true);
   13402                                 }
   13403                             }
   13404                         }
   13405                     }
   13406                 }
   13407             } else {
   13408                 String msg = "Permission Denial: " + intent.getAction()
   13409                         + " broadcast from " + callerPackage + " (pid=" + callingPid
   13410                         + ", uid=" + callingUid + ")"
   13411                         + " requires "
   13412                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
   13413                 Slog.w(TAG, msg);
   13414                 throw new SecurityException(msg);
   13415             }
   13416 
   13417         // Special case for adding a package: by default turn on compatibility
   13418         // mode.
   13419         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
   13420             Uri data = intent.getData();
   13421             String ssp;
   13422             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
   13423                 mCompatModePackages.handlePackageAddedLocked(ssp,
   13424                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
   13425             }
   13426         }
   13427 
   13428         /*
   13429          * If this is the time zone changed action, queue up a message that will reset the timezone
   13430          * of all currently running processes. This message will get queued up before the broadcast
   13431          * happens.
   13432          */
   13433         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
   13434             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
   13435         }
   13436 
   13437         if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
   13438             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
   13439         }
   13440 
   13441         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
   13442             ProxyProperties proxy = intent.getParcelableExtra("proxy");
   13443             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
   13444         }
   13445 
   13446         // Add to the sticky list if requested.
   13447         if (sticky) {
   13448             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
   13449                     callingPid, callingUid)
   13450                     != PackageManager.PERMISSION_GRANTED) {
   13451                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
   13452                         + callingPid + ", uid=" + callingUid
   13453                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13454                 Slog.w(TAG, msg);
   13455                 throw new SecurityException(msg);
   13456             }
   13457             if (requiredPermission != null) {
   13458                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
   13459                         + " and enforce permission " + requiredPermission);
   13460                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
   13461             }
   13462             if (intent.getComponent() != null) {
   13463                 throw new SecurityException(
   13464                         "Sticky broadcasts can't target a specific component");
   13465             }
   13466             // We use userId directly here, since the "all" target is maintained
   13467             // as a separate set of sticky broadcasts.
   13468             if (userId != UserHandle.USER_ALL) {
   13469                 // But first, if this is not a broadcast to all users, then
   13470                 // make sure it doesn't conflict with an existing broadcast to
   13471                 // all users.
   13472                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
   13473                         UserHandle.USER_ALL);
   13474                 if (stickies != null) {
   13475                     ArrayList<Intent> list = stickies.get(intent.getAction());
   13476                     if (list != null) {
   13477                         int N = list.size();
   13478                         int i;
   13479                         for (i=0; i<N; i++) {
   13480                             if (intent.filterEquals(list.get(i))) {
   13481                                 throw new IllegalArgumentException(
   13482                                         "Sticky broadcast " + intent + " for user "
   13483                                         + userId + " conflicts with existing global broadcast");
   13484                             }
   13485                         }
   13486                     }
   13487                 }
   13488             }
   13489             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13490             if (stickies == null) {
   13491                 stickies = new ArrayMap<String, ArrayList<Intent>>();
   13492                 mStickyBroadcasts.put(userId, stickies);
   13493             }
   13494             ArrayList<Intent> list = stickies.get(intent.getAction());
   13495             if (list == null) {
   13496                 list = new ArrayList<Intent>();
   13497                 stickies.put(intent.getAction(), list);
   13498             }
   13499             int N = list.size();
   13500             int i;
   13501             for (i=0; i<N; i++) {
   13502                 if (intent.filterEquals(list.get(i))) {
   13503                     // This sticky already exists, replace it.
   13504                     list.set(i, new Intent(intent));
   13505                     break;
   13506                 }
   13507             }
   13508             if (i >= N) {
   13509                 list.add(new Intent(intent));
   13510             }
   13511         }
   13512 
   13513         int[] users;
   13514         if (userId == UserHandle.USER_ALL) {
   13515             // Caller wants broadcast to go to all started users.
   13516             users = mStartedUserArray;
   13517         } else {
   13518             // Caller wants broadcast to go to one specific user.
   13519             users = new int[] {userId};
   13520         }
   13521 
   13522         // Figure out who all will receive this broadcast.
   13523         List receivers = null;
   13524         List<BroadcastFilter> registeredReceivers = null;
   13525         // Need to resolve the intent to interested receivers...
   13526         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
   13527                  == 0) {
   13528             receivers = collectReceiverComponents(intent, resolvedType, users);
   13529         }
   13530         if (intent.getComponent() == null) {
   13531             registeredReceivers = mReceiverResolver.queryIntent(intent,
   13532                     resolvedType, false, userId);
   13533         }
   13534 
   13535         final boolean replacePending =
   13536                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
   13537 
   13538         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
   13539                 + " replacePending=" + replacePending);
   13540 
   13541         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
   13542         if (!ordered && NR > 0) {
   13543             // If we are not serializing this broadcast, then send the
   13544             // registered receivers separately so they don't wait for the
   13545             // components to be launched.
   13546             final BroadcastQueue queue = broadcastQueueForIntent(intent);
   13547             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13548                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
   13549                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
   13550                     ordered, sticky, false, userId);
   13551             if (DEBUG_BROADCAST) Slog.v(
   13552                     TAG, "Enqueueing parallel broadcast " + r);
   13553             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
   13554             if (!replaced) {
   13555                 queue.enqueueParallelBroadcastLocked(r);
   13556                 queue.scheduleBroadcastsLocked();
   13557             }
   13558             registeredReceivers = null;
   13559             NR = 0;
   13560         }
   13561 
   13562         // Merge into one list.
   13563         int ir = 0;
   13564         if (receivers != null) {
   13565             // A special case for PACKAGE_ADDED: do not allow the package
   13566             // being added to see this broadcast.  This prevents them from
   13567             // using this as a back door to get run as soon as they are
   13568             // installed.  Maybe in the future we want to have a special install
   13569             // broadcast or such for apps, but we'd like to deliberately make
   13570             // this decision.
   13571             String skipPackages[] = null;
   13572             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
   13573                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
   13574                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
   13575                 Uri data = intent.getData();
   13576                 if (data != null) {
   13577                     String pkgName = data.getSchemeSpecificPart();
   13578                     if (pkgName != null) {
   13579                         skipPackages = new String[] { pkgName };
   13580                     }
   13581                 }
   13582             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
   13583                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   13584             }
   13585             if (skipPackages != null && (skipPackages.length > 0)) {
   13586                 for (String skipPackage : skipPackages) {
   13587                     if (skipPackage != null) {
   13588                         int NT = receivers.size();
   13589                         for (int it=0; it<NT; it++) {
   13590                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
   13591                             if (curt.activityInfo.packageName.equals(skipPackage)) {
   13592                                 receivers.remove(it);
   13593                                 it--;
   13594                                 NT--;
   13595                             }
   13596                         }
   13597                     }
   13598                 }
   13599             }
   13600 
   13601             int NT = receivers != null ? receivers.size() : 0;
   13602             int it = 0;
   13603             ResolveInfo curt = null;
   13604             BroadcastFilter curr = null;
   13605             while (it < NT && ir < NR) {
   13606                 if (curt == null) {
   13607                     curt = (ResolveInfo)receivers.get(it);
   13608                 }
   13609                 if (curr == null) {
   13610                     curr = registeredReceivers.get(ir);
   13611                 }
   13612                 if (curr.getPriority() >= curt.priority) {
   13613                     // Insert this broadcast record into the final list.
   13614                     receivers.add(it, curr);
   13615                     ir++;
   13616                     curr = null;
   13617                     it++;
   13618                     NT++;
   13619                 } else {
   13620                     // Skip to the next ResolveInfo in the final list.
   13621                     it++;
   13622                     curt = null;
   13623                 }
   13624             }
   13625         }
   13626         while (ir < NR) {
   13627             if (receivers == null) {
   13628                 receivers = new ArrayList();
   13629             }
   13630             receivers.add(registeredReceivers.get(ir));
   13631             ir++;
   13632         }
   13633 
   13634         if ((receivers != null && receivers.size() > 0)
   13635                 || resultTo != null) {
   13636             BroadcastQueue queue = broadcastQueueForIntent(intent);
   13637             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
   13638                     callerPackage, callingPid, callingUid, resolvedType,
   13639                     requiredPermission, appOp, receivers, resultTo, resultCode,
   13640                     resultData, map, ordered, sticky, false, userId);
   13641             if (DEBUG_BROADCAST) Slog.v(
   13642                     TAG, "Enqueueing ordered broadcast " + r
   13643                     + ": prev had " + queue.mOrderedBroadcasts.size());
   13644             if (DEBUG_BROADCAST) {
   13645                 int seq = r.intent.getIntExtra("seq", -1);
   13646                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
   13647             }
   13648             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
   13649             if (!replaced) {
   13650                 queue.enqueueOrderedBroadcastLocked(r);
   13651                 queue.scheduleBroadcastsLocked();
   13652             }
   13653         }
   13654 
   13655         return ActivityManager.BROADCAST_SUCCESS;
   13656     }
   13657 
   13658     final Intent verifyBroadcastLocked(Intent intent) {
   13659         // Refuse possible leaked file descriptors
   13660         if (intent != null && intent.hasFileDescriptors() == true) {
   13661             throw new IllegalArgumentException("File descriptors passed in Intent");
   13662         }
   13663 
   13664         int flags = intent.getFlags();
   13665 
   13666         if (!mProcessesReady) {
   13667             // if the caller really truly claims to know what they're doing, go
   13668             // ahead and allow the broadcast without launching any receivers
   13669             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
   13670                 intent = new Intent(intent);
   13671                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   13672             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
   13673                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
   13674                         + " before boot completion");
   13675                 throw new IllegalStateException("Cannot broadcast before boot completed");
   13676             }
   13677         }
   13678 
   13679         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
   13680             throw new IllegalArgumentException(
   13681                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
   13682         }
   13683 
   13684         return intent;
   13685     }
   13686 
   13687     public final int broadcastIntent(IApplicationThread caller,
   13688             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13689             int resultCode, String resultData, Bundle map,
   13690             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
   13691         enforceNotIsolatedCaller("broadcastIntent");
   13692         synchronized(this) {
   13693             intent = verifyBroadcastLocked(intent);
   13694 
   13695             final ProcessRecord callerApp = getRecordForAppLocked(caller);
   13696             final int callingPid = Binder.getCallingPid();
   13697             final int callingUid = Binder.getCallingUid();
   13698             final long origId = Binder.clearCallingIdentity();
   13699             int res = broadcastIntentLocked(callerApp,
   13700                     callerApp != null ? callerApp.info.packageName : null,
   13701                     intent, resolvedType, resultTo,
   13702                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
   13703                     callingPid, callingUid, userId);
   13704             Binder.restoreCallingIdentity(origId);
   13705             return res;
   13706         }
   13707     }
   13708 
   13709     int broadcastIntentInPackage(String packageName, int uid,
   13710             Intent intent, String resolvedType, IIntentReceiver resultTo,
   13711             int resultCode, String resultData, Bundle map,
   13712             String requiredPermission, boolean serialized, boolean sticky, int userId) {
   13713         synchronized(this) {
   13714             intent = verifyBroadcastLocked(intent);
   13715 
   13716             final long origId = Binder.clearCallingIdentity();
   13717             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
   13718                     resultTo, resultCode, resultData, map, requiredPermission,
   13719                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
   13720             Binder.restoreCallingIdentity(origId);
   13721             return res;
   13722         }
   13723     }
   13724 
   13725     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
   13726         // Refuse possible leaked file descriptors
   13727         if (intent != null && intent.hasFileDescriptors() == true) {
   13728             throw new IllegalArgumentException("File descriptors passed in Intent");
   13729         }
   13730 
   13731         userId = handleIncomingUser(Binder.getCallingPid(),
   13732                 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
   13733 
   13734         synchronized(this) {
   13735             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
   13736                     != PackageManager.PERMISSION_GRANTED) {
   13737                 String msg = "Permission Denial: unbroadcastIntent() from pid="
   13738                         + Binder.getCallingPid()
   13739                         + ", uid=" + Binder.getCallingUid()
   13740                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
   13741                 Slog.w(TAG, msg);
   13742                 throw new SecurityException(msg);
   13743             }
   13744             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
   13745             if (stickies != null) {
   13746                 ArrayList<Intent> list = stickies.get(intent.getAction());
   13747                 if (list != null) {
   13748                     int N = list.size();
   13749                     int i;
   13750                     for (i=0; i<N; i++) {
   13751                         if (intent.filterEquals(list.get(i))) {
   13752                             list.remove(i);
   13753                             break;
   13754                         }
   13755                     }
   13756                     if (list.size() <= 0) {
   13757                         stickies.remove(intent.getAction());
   13758                     }
   13759                 }
   13760                 if (stickies.size() <= 0) {
   13761                     mStickyBroadcasts.remove(userId);
   13762                 }
   13763             }
   13764         }
   13765     }
   13766 
   13767     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
   13768             String resultData, Bundle resultExtras, boolean resultAbort) {
   13769         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
   13770         if (r == null) {
   13771             Slog.w(TAG, "finishReceiver called but not found on queue");
   13772             return false;
   13773         }
   13774 
   13775         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
   13776     }
   13777 
   13778     void backgroundServicesFinishedLocked(int userId) {
   13779         for (BroadcastQueue queue : mBroadcastQueues) {
   13780             queue.backgroundServicesFinishedLocked(userId);
   13781         }
   13782     }
   13783 
   13784     public void finishReceiver(IBinder who, int resultCode, String resultData,
   13785             Bundle resultExtras, boolean resultAbort) {
   13786         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
   13787 
   13788         // Refuse possible leaked file descriptors
   13789         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
   13790             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13791         }
   13792 
   13793         final long origId = Binder.clearCallingIdentity();
   13794         try {
   13795             boolean doNext = false;
   13796             BroadcastRecord r;
   13797 
   13798             synchronized(this) {
   13799                 r = broadcastRecordForReceiverLocked(who);
   13800                 if (r != null) {
   13801                     doNext = r.queue.finishReceiverLocked(r, resultCode,
   13802                         resultData, resultExtras, resultAbort, true);
   13803                 }
   13804             }
   13805 
   13806             if (doNext) {
   13807                 r.queue.processNextBroadcast(false);
   13808             }
   13809             trimApplications();
   13810         } finally {
   13811             Binder.restoreCallingIdentity(origId);
   13812         }
   13813     }
   13814 
   13815     // =========================================================
   13816     // INSTRUMENTATION
   13817     // =========================================================
   13818 
   13819     public boolean startInstrumentation(ComponentName className,
   13820             String profileFile, int flags, Bundle arguments,
   13821             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
   13822             int userId) {
   13823         enforceNotIsolatedCaller("startInstrumentation");
   13824         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   13825                 userId, false, true, "startInstrumentation", null);
   13826         // Refuse possible leaked file descriptors
   13827         if (arguments != null && arguments.hasFileDescriptors()) {
   13828             throw new IllegalArgumentException("File descriptors passed in Bundle");
   13829         }
   13830 
   13831         synchronized(this) {
   13832             InstrumentationInfo ii = null;
   13833             ApplicationInfo ai = null;
   13834             try {
   13835                 ii = mContext.getPackageManager().getInstrumentationInfo(
   13836                     className, STOCK_PM_FLAGS);
   13837                 ai = AppGlobals.getPackageManager().getApplicationInfo(
   13838                         ii.targetPackage, STOCK_PM_FLAGS, userId);
   13839             } catch (PackageManager.NameNotFoundException e) {
   13840             } catch (RemoteException e) {
   13841             }
   13842             if (ii == null) {
   13843                 reportStartInstrumentationFailure(watcher, className,
   13844                         "Unable to find instrumentation info for: " + className);
   13845                 return false;
   13846             }
   13847             if (ai == null) {
   13848                 reportStartInstrumentationFailure(watcher, className,
   13849                         "Unable to find instrumentation target package: " + ii.targetPackage);
   13850                 return false;
   13851             }
   13852 
   13853             int match = mContext.getPackageManager().checkSignatures(
   13854                     ii.targetPackage, ii.packageName);
   13855             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
   13856                 String msg = "Permission Denial: starting instrumentation "
   13857                         + className + " from pid="
   13858                         + Binder.getCallingPid()
   13859                         + ", uid=" + Binder.getCallingPid()
   13860                         + " not allowed because package " + ii.packageName
   13861                         + " does not have a signature matching the target "
   13862                         + ii.targetPackage;
   13863                 reportStartInstrumentationFailure(watcher, className, msg);
   13864                 throw new SecurityException(msg);
   13865             }
   13866 
   13867             final long origId = Binder.clearCallingIdentity();
   13868             // Instrumentation can kill and relaunch even persistent processes
   13869             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
   13870                     "start instr");
   13871             ProcessRecord app = addAppLocked(ai, false);
   13872             app.instrumentationClass = className;
   13873             app.instrumentationInfo = ai;
   13874             app.instrumentationProfileFile = profileFile;
   13875             app.instrumentationArguments = arguments;
   13876             app.instrumentationWatcher = watcher;
   13877             app.instrumentationUiAutomationConnection = uiAutomationConnection;
   13878             app.instrumentationResultClass = className;
   13879             Binder.restoreCallingIdentity(origId);
   13880         }
   13881 
   13882         return true;
   13883     }
   13884 
   13885     /**
   13886      * Report errors that occur while attempting to start Instrumentation.  Always writes the
   13887      * error to the logs, but if somebody is watching, send the report there too.  This enables
   13888      * the "am" command to report errors with more information.
   13889      *
   13890      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
   13891      * @param cn The component name of the instrumentation.
   13892      * @param report The error report.
   13893      */
   13894     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
   13895             ComponentName cn, String report) {
   13896         Slog.w(TAG, report);
   13897         try {
   13898             if (watcher != null) {
   13899                 Bundle results = new Bundle();
   13900                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
   13901                 results.putString("Error", report);
   13902                 watcher.instrumentationStatus(cn, -1, results);
   13903             }
   13904         } catch (RemoteException e) {
   13905             Slog.w(TAG, e);
   13906         }
   13907     }
   13908 
   13909     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
   13910         if (app.instrumentationWatcher != null) {
   13911             try {
   13912                 // NOTE:  IInstrumentationWatcher *must* be oneway here
   13913                 app.instrumentationWatcher.instrumentationFinished(
   13914                     app.instrumentationClass,
   13915                     resultCode,
   13916                     results);
   13917             } catch (RemoteException e) {
   13918             }
   13919         }
   13920         if (app.instrumentationUiAutomationConnection != null) {
   13921             try {
   13922                 app.instrumentationUiAutomationConnection.shutdown();
   13923             } catch (RemoteException re) {
   13924                 /* ignore */
   13925             }
   13926             // Only a UiAutomation can set this flag and now that
   13927             // it is finished we make sure it is reset to its default.
   13928             mUserIsMonkey = false;
   13929         }
   13930         app.instrumentationWatcher = null;
   13931         app.instrumentationUiAutomationConnection = null;
   13932         app.instrumentationClass = null;
   13933         app.instrumentationInfo = null;
   13934         app.instrumentationProfileFile = null;
   13935         app.instrumentationArguments = null;
   13936 
   13937         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
   13938                 "finished inst");
   13939     }
   13940 
   13941     public void finishInstrumentation(IApplicationThread target,
   13942             int resultCode, Bundle results) {
   13943         int userId = UserHandle.getCallingUserId();
   13944         // Refuse possible leaked file descriptors
   13945         if (results != null && results.hasFileDescriptors()) {
   13946             throw new IllegalArgumentException("File descriptors passed in Intent");
   13947         }
   13948 
   13949         synchronized(this) {
   13950             ProcessRecord app = getRecordForAppLocked(target);
   13951             if (app == null) {
   13952                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
   13953                 return;
   13954             }
   13955             final long origId = Binder.clearCallingIdentity();
   13956             finishInstrumentationLocked(app, resultCode, results);
   13957             Binder.restoreCallingIdentity(origId);
   13958         }
   13959     }
   13960 
   13961     // =========================================================
   13962     // CONFIGURATION
   13963     // =========================================================
   13964 
   13965     public ConfigurationInfo getDeviceConfigurationInfo() {
   13966         ConfigurationInfo config = new ConfigurationInfo();
   13967         synchronized (this) {
   13968             config.reqTouchScreen = mConfiguration.touchscreen;
   13969             config.reqKeyboardType = mConfiguration.keyboard;
   13970             config.reqNavigation = mConfiguration.navigation;
   13971             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
   13972                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
   13973                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
   13974             }
   13975             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
   13976                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
   13977                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
   13978             }
   13979             config.reqGlEsVersion = GL_ES_VERSION;
   13980         }
   13981         return config;
   13982     }
   13983 
   13984     ActivityStack getFocusedStack() {
   13985         return mStackSupervisor.getFocusedStack();
   13986     }
   13987 
   13988     public Configuration getConfiguration() {
   13989         Configuration ci;
   13990         synchronized(this) {
   13991             ci = new Configuration(mConfiguration);
   13992         }
   13993         return ci;
   13994     }
   13995 
   13996     public void updatePersistentConfiguration(Configuration values) {
   13997         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   13998                 "updateConfiguration()");
   13999         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
   14000                 "updateConfiguration()");
   14001         if (values == null) {
   14002             throw new NullPointerException("Configuration must not be null");
   14003         }
   14004 
   14005         synchronized(this) {
   14006             final long origId = Binder.clearCallingIdentity();
   14007             updateConfigurationLocked(values, null, true, false);
   14008             Binder.restoreCallingIdentity(origId);
   14009         }
   14010     }
   14011 
   14012     public void updateConfiguration(Configuration values) {
   14013         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
   14014                 "updateConfiguration()");
   14015 
   14016         synchronized(this) {
   14017             if (values == null && mWindowManager != null) {
   14018                 // sentinel: fetch the current configuration from the window manager
   14019                 values = mWindowManager.computeNewConfiguration();
   14020             }
   14021 
   14022             if (mWindowManager != null) {
   14023                 mProcessList.applyDisplaySize(mWindowManager);
   14024             }
   14025 
   14026             final long origId = Binder.clearCallingIdentity();
   14027             if (values != null) {
   14028                 Settings.System.clearConfiguration(values);
   14029             }
   14030             updateConfigurationLocked(values, null, false, false);
   14031             Binder.restoreCallingIdentity(origId);
   14032         }
   14033     }
   14034 
   14035     /**
   14036      * Do either or both things: (1) change the current configuration, and (2)
   14037      * make sure the given activity is running with the (now) current
   14038      * configuration.  Returns true if the activity has been left running, or
   14039      * false if <var>starting</var> is being destroyed to match the new
   14040      * configuration.
   14041      * @param persistent TODO
   14042      */
   14043     boolean updateConfigurationLocked(Configuration values,
   14044             ActivityRecord starting, boolean persistent, boolean initLocale) {
   14045         // do nothing if we are headless
   14046         if (mHeadless) return true;
   14047 
   14048         int changes = 0;
   14049 
   14050         if (values != null) {
   14051             Configuration newConfig = new Configuration(mConfiguration);
   14052             changes = newConfig.updateFrom(values);
   14053             if (changes != 0) {
   14054                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
   14055                     Slog.i(TAG, "Updating configuration to: " + values);
   14056                 }
   14057 
   14058                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
   14059 
   14060                 if (values.locale != null && !initLocale) {
   14061                     saveLocaleLocked(values.locale,
   14062                                      !values.locale.equals(mConfiguration.locale),
   14063                                      values.userSetLocale);
   14064                 }
   14065 
   14066                 mConfigurationSeq++;
   14067                 if (mConfigurationSeq <= 0) {
   14068                     mConfigurationSeq = 1;
   14069                 }
   14070                 newConfig.seq = mConfigurationSeq;
   14071                 mConfiguration = newConfig;
   14072                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
   14073 
   14074                 final Configuration configCopy = new Configuration(mConfiguration);
   14075 
   14076                 // TODO: If our config changes, should we auto dismiss any currently
   14077                 // showing dialogs?
   14078                 mShowDialogs = shouldShowDialogs(newConfig);
   14079 
   14080                 AttributeCache ac = AttributeCache.instance();
   14081                 if (ac != null) {
   14082                     ac.updateConfiguration(configCopy);
   14083                 }
   14084 
   14085                 // Make sure all resources in our process are updated
   14086                 // right now, so that anyone who is going to retrieve
   14087                 // resource values after we return will be sure to get
   14088                 // the new ones.  This is especially important during
   14089                 // boot, where the first config change needs to guarantee
   14090                 // all resources have that config before following boot
   14091                 // code is executed.
   14092                 mSystemThread.applyConfigurationToResources(configCopy);
   14093 
   14094                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
   14095                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
   14096                     msg.obj = new Configuration(configCopy);
   14097                     mHandler.sendMessage(msg);
   14098                 }
   14099 
   14100                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
   14101                     ProcessRecord app = mLruProcesses.get(i);
   14102                     try {
   14103                         if (app.thread != null) {
   14104                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
   14105                                     + app.processName + " new config " + mConfiguration);
   14106                             app.thread.scheduleConfigurationChanged(configCopy);
   14107                         }
   14108                     } catch (Exception e) {
   14109                     }
   14110                 }
   14111                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
   14112                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   14113                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
   14114                         | Intent.FLAG_RECEIVER_FOREGROUND);
   14115                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
   14116                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
   14117                         Process.SYSTEM_UID, UserHandle.USER_ALL);
   14118                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
   14119                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
   14120                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   14121                     broadcastIntentLocked(null, null, intent,
   14122                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   14123                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   14124                 }
   14125             }
   14126         }
   14127 
   14128         boolean kept = true;
   14129         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
   14130         if (changes != 0 && starting == null) {
   14131             // If the configuration changed, and the caller is not already
   14132             // in the process of starting an activity, then find the top
   14133             // activity to check if its configuration needs to change.
   14134             starting = mainStack.topRunningActivityLocked(null);
   14135         }
   14136 
   14137         if (starting != null) {
   14138             kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
   14139             // And we need to make sure at this point that all other activities
   14140             // are made visible with the correct configuration.
   14141             mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
   14142         }
   14143 
   14144         if (values != null && mWindowManager != null) {
   14145             mWindowManager.setNewConfiguration(mConfiguration);
   14146         }
   14147 
   14148         return kept;
   14149     }
   14150 
   14151     /**
   14152      * Decide based on the configuration whether we should shouw the ANR,
   14153      * crash, etc dialogs.  The idea is that if there is no affordnace to
   14154      * press the on-screen buttons, we shouldn't show the dialog.
   14155      *
   14156      * A thought: SystemUI might also want to get told about this, the Power
   14157      * dialog / global actions also might want different behaviors.
   14158      */
   14159     private static final boolean shouldShowDialogs(Configuration config) {
   14160         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
   14161                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
   14162     }
   14163 
   14164     /**
   14165      * Save the locale.  You must be inside a synchronized (this) block.
   14166      */
   14167     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
   14168         if(isDiff) {
   14169             SystemProperties.set("user.language", l.getLanguage());
   14170             SystemProperties.set("user.region", l.getCountry());
   14171         }
   14172 
   14173         if(isPersist) {
   14174             SystemProperties.set("persist.sys.language", l.getLanguage());
   14175             SystemProperties.set("persist.sys.country", l.getCountry());
   14176             SystemProperties.set("persist.sys.localevar", l.getVariant());
   14177         }
   14178     }
   14179 
   14180     @Override
   14181     public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
   14182         ActivityRecord srec = ActivityRecord.forToken(token);
   14183         return srec != null && srec.task.affinity != null &&
   14184                 srec.task.affinity.equals(destAffinity);
   14185     }
   14186 
   14187     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
   14188             Intent resultData) {
   14189 
   14190         synchronized (this) {
   14191             final ActivityStack stack = ActivityRecord.getStackLocked(token);
   14192             if (stack != null) {
   14193                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
   14194             }
   14195             return false;
   14196         }
   14197     }
   14198 
   14199     public int getLaunchedFromUid(IBinder activityToken) {
   14200         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   14201         if (srec == null) {
   14202             return -1;
   14203         }
   14204         return srec.launchedFromUid;
   14205     }
   14206 
   14207     public String getLaunchedFromPackage(IBinder activityToken) {
   14208         ActivityRecord srec = ActivityRecord.forToken(activityToken);
   14209         if (srec == null) {
   14210             return null;
   14211         }
   14212         return srec.launchedFromPackage;
   14213     }
   14214 
   14215     // =========================================================
   14216     // LIFETIME MANAGEMENT
   14217     // =========================================================
   14218 
   14219     // Returns which broadcast queue the app is the current [or imminent] receiver
   14220     // on, or 'null' if the app is not an active broadcast recipient.
   14221     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
   14222         BroadcastRecord r = app.curReceiver;
   14223         if (r != null) {
   14224             return r.queue;
   14225         }
   14226 
   14227         // It's not the current receiver, but it might be starting up to become one
   14228         synchronized (this) {
   14229             for (BroadcastQueue queue : mBroadcastQueues) {
   14230                 r = queue.mPendingBroadcast;
   14231                 if (r != null && r.curApp == app) {
   14232                     // found it; report which queue it's in
   14233                     return queue;
   14234                 }
   14235             }
   14236         }
   14237 
   14238         return null;
   14239     }
   14240 
   14241     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
   14242             boolean doingAll, long now) {
   14243         if (mAdjSeq == app.adjSeq) {
   14244             // This adjustment has already been computed.
   14245             return app.curRawAdj;
   14246         }
   14247 
   14248         if (app.thread == null) {
   14249             app.adjSeq = mAdjSeq;
   14250             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14251             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14252             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
   14253         }
   14254 
   14255         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
   14256         app.adjSource = null;
   14257         app.adjTarget = null;
   14258         app.empty = false;
   14259         app.cached = false;
   14260 
   14261         final int activitiesSize = app.activities.size();
   14262 
   14263         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
   14264             // The max adjustment doesn't allow this app to be anything
   14265             // below foreground, so it is not worth doing work for it.
   14266             app.adjType = "fixed";
   14267             app.adjSeq = mAdjSeq;
   14268             app.curRawAdj = app.maxAdj;
   14269             app.foregroundActivities = false;
   14270             app.keeping = true;
   14271             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
   14272             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
   14273             // System process can do UI, and when they do we want to have
   14274             // them trim their memory after the user leaves the UI.  To
   14275             // facilitate this, here we need to determine whether or not it
   14276             // is currently showing UI.
   14277             app.systemNoUi = true;
   14278             if (app == TOP_APP) {
   14279                 app.systemNoUi = false;
   14280             } else if (activitiesSize > 0) {
   14281                 for (int j = 0; j < activitiesSize; j++) {
   14282                     final ActivityRecord r = app.activities.get(j);
   14283                     if (r.visible) {
   14284                         app.systemNoUi = false;
   14285                     }
   14286                 }
   14287             }
   14288             if (!app.systemNoUi) {
   14289                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
   14290             }
   14291             return (app.curAdj=app.maxAdj);
   14292         }
   14293 
   14294         app.keeping = false;
   14295         app.systemNoUi = false;
   14296 
   14297         // Determine the importance of the process, starting with most
   14298         // important to least, and assign an appropriate OOM adjustment.
   14299         int adj;
   14300         int schedGroup;
   14301         int procState;
   14302         boolean foregroundActivities = false;
   14303         boolean interesting = false;
   14304         BroadcastQueue queue;
   14305         if (app == TOP_APP) {
   14306             // The last app on the list is the foreground app.
   14307             adj = ProcessList.FOREGROUND_APP_ADJ;
   14308             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14309             app.adjType = "top-activity";
   14310             foregroundActivities = true;
   14311             interesting = true;
   14312             procState = ActivityManager.PROCESS_STATE_TOP;
   14313         } else if (app.instrumentationClass != null) {
   14314             // Don't want to kill running instrumentation.
   14315             adj = ProcessList.FOREGROUND_APP_ADJ;
   14316             schedGroup = Process.THREAD_GROUP_DEFAULT;
   14317             app.adjType = "instrumentation";
   14318             interesting = true;
   14319             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14320         } else if ((queue = isReceivingBroadcast(app)) != null) {
   14321             // An app that is currently receiving a broadcast also
   14322             // counts as being in the foreground for OOM killer purposes.
   14323             // It's placed in a sched group based on the nature of the
   14324             // broadcast as reflected by which queue it's active in.
   14325             adj = ProcessList.FOREGROUND_APP_ADJ;
   14326             schedGroup = (queue == mFgBroadcastQueue)
   14327                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14328             app.adjType = "broadcast";
   14329             procState = ActivityManager.PROCESS_STATE_RECEIVER;
   14330         } else if (app.executingServices.size() > 0) {
   14331             // An app that is currently executing a service callback also
   14332             // counts as being in the foreground.
   14333             adj = ProcessList.FOREGROUND_APP_ADJ;
   14334             schedGroup = app.execServicesFg ?
   14335                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14336             app.adjType = "exec-service";
   14337             procState = ActivityManager.PROCESS_STATE_SERVICE;
   14338             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
   14339         } else {
   14340             // As far as we know the process is empty.  We may change our mind later.
   14341             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14342             // At this point we don't actually know the adjustment.  Use the cached adj
   14343             // value that the caller wants us to.
   14344             adj = cachedAdj;
   14345             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14346             app.cached = true;
   14347             app.empty = true;
   14348             app.adjType = "cch-empty";
   14349         }
   14350 
   14351         // Examine all activities if not already foreground.
   14352         if (!foregroundActivities && activitiesSize > 0) {
   14353             for (int j = 0; j < activitiesSize; j++) {
   14354                 final ActivityRecord r = app.activities.get(j);
   14355                 if (r.app != app) {
   14356                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
   14357                             + app + "?!?");
   14358                     continue;
   14359                 }
   14360                 if (r.visible) {
   14361                     // App has a visible activity; only upgrade adjustment.
   14362                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14363                         adj = ProcessList.VISIBLE_APP_ADJ;
   14364                         app.adjType = "visible";
   14365                     }
   14366                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14367                         procState = ActivityManager.PROCESS_STATE_TOP;
   14368                     }
   14369                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14370                     app.cached = false;
   14371                     app.empty = false;
   14372                     foregroundActivities = true;
   14373                     break;
   14374                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
   14375                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14376                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14377                         app.adjType = "pausing";
   14378                     }
   14379                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
   14380                         procState = ActivityManager.PROCESS_STATE_TOP;
   14381                     }
   14382                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14383                     app.cached = false;
   14384                     app.empty = false;
   14385                     foregroundActivities = true;
   14386                 } else if (r.state == ActivityState.STOPPING) {
   14387                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14388                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14389                         app.adjType = "stopping";
   14390                     }
   14391                     // For the process state, we will at this point consider the
   14392                     // process to be cached.  It will be cached either as an activity
   14393                     // or empty depending on whether the activity is finishing.  We do
   14394                     // this so that we can treat the process as cached for purposes of
   14395                     // memory trimming (determing current memory level, trim command to
   14396                     // send to process) since there can be an arbitrary number of stopping
   14397                     // processes and they should soon all go into the cached state.
   14398                     if (!r.finishing) {
   14399                         if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14400                             procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14401                         }
   14402                     }
   14403                     app.cached = false;
   14404                     app.empty = false;
   14405                     foregroundActivities = true;
   14406                 } else {
   14407                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14408                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
   14409                         app.adjType = "cch-act";
   14410                     }
   14411                 }
   14412             }
   14413         }
   14414 
   14415         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14416             if (app.foregroundServices) {
   14417                 // The user is aware of this app, so make it visible.
   14418                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14419                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14420                 app.cached = false;
   14421                 app.adjType = "fg-service";
   14422                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14423             } else if (app.forcingToForeground != null) {
   14424                 // The user is aware of this app, so make it visible.
   14425                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14426                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14427                 app.cached = false;
   14428                 app.adjType = "force-fg";
   14429                 app.adjSource = app.forcingToForeground;
   14430                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14431             }
   14432         }
   14433 
   14434         if (app.foregroundServices) {
   14435             interesting = true;
   14436         }
   14437 
   14438         if (app == mHeavyWeightProcess) {
   14439             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14440                 // We don't want to kill the current heavy-weight process.
   14441                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
   14442                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14443                 app.cached = false;
   14444                 app.adjType = "heavy";
   14445             }
   14446             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   14447                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
   14448             }
   14449         }
   14450 
   14451         if (app == mHomeProcess) {
   14452             if (adj > ProcessList.HOME_APP_ADJ) {
   14453                 // This process is hosting what we currently consider to be the
   14454                 // home app, so we don't want to let it go into the background.
   14455                 adj = ProcessList.HOME_APP_ADJ;
   14456                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14457                 app.cached = false;
   14458                 app.adjType = "home";
   14459             }
   14460             if (procState > ActivityManager.PROCESS_STATE_HOME) {
   14461                 procState = ActivityManager.PROCESS_STATE_HOME;
   14462             }
   14463         }
   14464 
   14465         if (app == mPreviousProcess && app.activities.size() > 0) {
   14466             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
   14467                 // This was the previous process that showed UI to the user.
   14468                 // We want to try to keep it around more aggressively, to give
   14469                 // a good experience around switching between two apps.
   14470                 adj = ProcessList.PREVIOUS_APP_ADJ;
   14471                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
   14472                 app.cached = false;
   14473                 app.adjType = "previous";
   14474             }
   14475             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
   14476                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
   14477             }
   14478         }
   14479 
   14480         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
   14481                 + " reason=" + app.adjType);
   14482 
   14483         // By default, we use the computed adjustment.  It may be changed if
   14484         // there are applications dependent on our services or providers, but
   14485         // this gives us a baseline and makes sure we don't get into an
   14486         // infinite recursion.
   14487         app.adjSeq = mAdjSeq;
   14488         app.curRawAdj = adj;
   14489         app.hasStartedServices = false;
   14490 
   14491         if (mBackupTarget != null && app == mBackupTarget.app) {
   14492             // If possible we want to avoid killing apps while they're being backed up
   14493             if (adj > ProcessList.BACKUP_APP_ADJ) {
   14494                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
   14495                 adj = ProcessList.BACKUP_APP_ADJ;
   14496                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14497                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14498                 }
   14499                 app.adjType = "backup";
   14500                 app.cached = false;
   14501             }
   14502             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
   14503                 procState = ActivityManager.PROCESS_STATE_BACKUP;
   14504             }
   14505         }
   14506 
   14507         boolean mayBeTop = false;
   14508 
   14509         for (int is = app.services.size()-1;
   14510                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14511                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14512                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14513                 is--) {
   14514             ServiceRecord s = app.services.valueAt(is);
   14515             if (s.startRequested) {
   14516                 app.hasStartedServices = true;
   14517                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
   14518                     procState = ActivityManager.PROCESS_STATE_SERVICE;
   14519                 }
   14520                 if (app.hasShownUi && app != mHomeProcess) {
   14521                     // If this process has shown some UI, let it immediately
   14522                     // go to the LRU list because it may be pretty heavy with
   14523                     // UI stuff.  We'll tag it with a label just to help
   14524                     // debug and understand what is going on.
   14525                     if (adj > ProcessList.SERVICE_ADJ) {
   14526                         app.adjType = "cch-started-ui-services";
   14527                     }
   14528                 } else {
   14529                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14530                         // This service has seen some activity within
   14531                         // recent memory, so we will keep its process ahead
   14532                         // of the background processes.
   14533                         if (adj > ProcessList.SERVICE_ADJ) {
   14534                             adj = ProcessList.SERVICE_ADJ;
   14535                             app.adjType = "started-services";
   14536                             app.cached = false;
   14537                         }
   14538                     }
   14539                     // If we have let the service slide into the background
   14540                     // state, still have some text describing what it is doing
   14541                     // even though the service no longer has an impact.
   14542                     if (adj > ProcessList.SERVICE_ADJ) {
   14543                         app.adjType = "cch-started-services";
   14544                     }
   14545                 }
   14546                 // Don't kill this process because it is doing work; it
   14547                 // has said it is doing work.
   14548                 app.keeping = true;
   14549             }
   14550             for (int conni = s.connections.size()-1;
   14551                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14552                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14553                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14554                     conni--) {
   14555                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
   14556                 for (int i = 0;
   14557                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
   14558                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14559                                 || procState > ActivityManager.PROCESS_STATE_TOP);
   14560                         i++) {
   14561                     // XXX should compute this based on the max of
   14562                     // all connected clients.
   14563                     ConnectionRecord cr = clist.get(i);
   14564                     if (cr.binding.client == app) {
   14565                         // Binding to ourself is not interesting.
   14566                         continue;
   14567                     }
   14568                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
   14569                         ProcessRecord client = cr.binding.client;
   14570                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
   14571                                 TOP_APP, doingAll, now);
   14572                         int clientProcState = client.curProcState;
   14573                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14574                             // If the other app is cached for any reason, for purposes here
   14575                             // we are going to consider it empty.  The specific cached state
   14576                             // doesn't propagate except under certain conditions.
   14577                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14578                         }
   14579                         String adjType = null;
   14580                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
   14581                             // Not doing bind OOM management, so treat
   14582                             // this guy more like a started service.
   14583                             if (app.hasShownUi && app != mHomeProcess) {
   14584                                 // If this process has shown some UI, let it immediately
   14585                                 // go to the LRU list because it may be pretty heavy with
   14586                                 // UI stuff.  We'll tag it with a label just to help
   14587                                 // debug and understand what is going on.
   14588                                 if (adj > clientAdj) {
   14589                                     adjType = "cch-bound-ui-services";
   14590                                 }
   14591                                 app.cached = false;
   14592                                 clientAdj = adj;
   14593                                 clientProcState = procState;
   14594                             } else {
   14595                                 if (now >= (s.lastActivity
   14596                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
   14597                                     // This service has not seen activity within
   14598                                     // recent memory, so allow it to drop to the
   14599                                     // LRU list if there is no other reason to keep
   14600                                     // it around.  We'll also tag it with a label just
   14601                                     // to help debug and undertand what is going on.
   14602                                     if (adj > clientAdj) {
   14603                                         adjType = "cch-bound-services";
   14604                                     }
   14605                                     clientAdj = adj;
   14606                                 }
   14607                             }
   14608                         }
   14609                         if (adj > clientAdj) {
   14610                             // If this process has recently shown UI, and
   14611                             // the process that is binding to it is less
   14612                             // important than being visible, then we don't
   14613                             // care about the binding as much as we care
   14614                             // about letting this process get into the LRU
   14615                             // list to be killed and restarted if needed for
   14616                             // memory.
   14617                             if (app.hasShownUi && app != mHomeProcess
   14618                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14619                                 adjType = "cch-bound-ui-services";
   14620                             } else {
   14621                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
   14622                                         |Context.BIND_IMPORTANT)) != 0) {
   14623                                     adj = clientAdj;
   14624                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
   14625                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
   14626                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14627                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
   14628                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
   14629                                     adj = clientAdj;
   14630                                 } else {
   14631                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
   14632                                         adj = ProcessList.VISIBLE_APP_ADJ;
   14633                                     }
   14634                                 }
   14635                                 if (!client.cached) {
   14636                                     app.cached = false;
   14637                                 }
   14638                                 if (client.keeping) {
   14639                                     app.keeping = true;
   14640                                 }
   14641                                 adjType = "service";
   14642                             }
   14643                         }
   14644                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14645                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14646                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14647                             }
   14648                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14649                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14650                                     // Special handling of clients who are in the top state.
   14651                                     // We *may* want to consider this process to be in the
   14652                                     // top state as well, but only if there is not another
   14653                                     // reason for it to be running.  Being on the top is a
   14654                                     // special state, meaning you are specifically running
   14655                                     // for the current top app.  If the process is already
   14656                                     // running in the background for some other reason, it
   14657                                     // is more important to continue considering it to be
   14658                                     // in the background state.
   14659                                     mayBeTop = true;
   14660                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14661                                 } else {
   14662                                     // Special handling for above-top states (persistent
   14663                                     // processes).  These should not bring the current process
   14664                                     // into the top state, since they are not on top.  Instead
   14665                                     // give them the best state after that.
   14666                                     clientProcState =
   14667                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14668                                 }
   14669                             }
   14670                         } else {
   14671                             if (clientProcState <
   14672                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
   14673                                 clientProcState =
   14674                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
   14675                             }
   14676                         }
   14677                         if (procState > clientProcState) {
   14678                             procState = clientProcState;
   14679                         }
   14680                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   14681                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
   14682                             app.pendingUiClean = true;
   14683                         }
   14684                         if (adjType != null) {
   14685                             app.adjType = adjType;
   14686                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14687                                     .REASON_SERVICE_IN_USE;
   14688                             app.adjSource = cr.binding.client;
   14689                             app.adjSourceOom = clientAdj;
   14690                             app.adjTarget = s.name;
   14691                         }
   14692                     }
   14693                     final ActivityRecord a = cr.activity;
   14694                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
   14695                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
   14696                                 (a.visible || a.state == ActivityState.RESUMED
   14697                                  || a.state == ActivityState.PAUSING)) {
   14698                             adj = ProcessList.FOREGROUND_APP_ADJ;
   14699                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
   14700                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14701                             }
   14702                             app.cached = false;
   14703                             app.adjType = "service";
   14704                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14705                                     .REASON_SERVICE_IN_USE;
   14706                             app.adjSource = a;
   14707                             app.adjSourceOom = adj;
   14708                             app.adjTarget = s.name;
   14709                         }
   14710                     }
   14711                 }
   14712             }
   14713         }
   14714 
   14715         for (int provi = app.pubProviders.size()-1;
   14716                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14717                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14718                         || procState > ActivityManager.PROCESS_STATE_TOP);
   14719                 provi--) {
   14720             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
   14721             for (int i = cpr.connections.size()-1;
   14722                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
   14723                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
   14724                             || procState > ActivityManager.PROCESS_STATE_TOP);
   14725                     i--) {
   14726                 ContentProviderConnection conn = cpr.connections.get(i);
   14727                 ProcessRecord client = conn.client;
   14728                 if (client == app) {
   14729                     // Being our own client is not interesting.
   14730                     continue;
   14731                 }
   14732                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
   14733                 int clientProcState = client.curProcState;
   14734                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
   14735                     // If the other app is cached for any reason, for purposes here
   14736                     // we are going to consider it empty.
   14737                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14738                 }
   14739                 if (adj > clientAdj) {
   14740                     if (app.hasShownUi && app != mHomeProcess
   14741                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
   14742                         app.adjType = "cch-ui-provider";
   14743                     } else {
   14744                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
   14745                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
   14746                         app.adjType = "provider";
   14747                     }
   14748                     app.cached &= client.cached;
   14749                     app.keeping |= client.keeping;
   14750                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
   14751                             .REASON_PROVIDER_IN_USE;
   14752                     app.adjSource = client;
   14753                     app.adjSourceOom = clientAdj;
   14754                     app.adjTarget = cpr.name;
   14755                 }
   14756                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
   14757                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
   14758                         // Special handling of clients who are in the top state.
   14759                         // We *may* want to consider this process to be in the
   14760                         // top state as well, but only if there is not another
   14761                         // reason for it to be running.  Being on the top is a
   14762                         // special state, meaning you are specifically running
   14763                         // for the current top app.  If the process is already
   14764                         // running in the background for some other reason, it
   14765                         // is more important to continue considering it to be
   14766                         // in the background state.
   14767                         mayBeTop = true;
   14768                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
   14769                     } else {
   14770                         // Special handling for above-top states (persistent
   14771                         // processes).  These should not bring the current process
   14772                         // into the top state, since they are not on top.  Instead
   14773                         // give them the best state after that.
   14774                         clientProcState =
   14775                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14776                     }
   14777                 }
   14778                 if (procState > clientProcState) {
   14779                     procState = clientProcState;
   14780                 }
   14781                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
   14782                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14783                 }
   14784             }
   14785             // If the provider has external (non-framework) process
   14786             // dependencies, ensure that its adjustment is at least
   14787             // FOREGROUND_APP_ADJ.
   14788             if (cpr.hasExternalProcessHandles()) {
   14789                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
   14790                     adj = ProcessList.FOREGROUND_APP_ADJ;
   14791                     schedGroup = Process.THREAD_GROUP_DEFAULT;
   14792                     app.cached = false;
   14793                     app.keeping = true;
   14794                     app.adjType = "provider";
   14795                     app.adjTarget = cpr.name;
   14796                 }
   14797                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
   14798                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14799                 }
   14800             }
   14801         }
   14802 
   14803         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
   14804             // A client of one of our services or providers is in the top state.  We
   14805             // *may* want to be in the top state, but not if we are already running in
   14806             // the background for some other reason.  For the decision here, we are going
   14807             // to pick out a few specific states that we want to remain in when a client
   14808             // is top (states that tend to be longer-term) and otherwise allow it to go
   14809             // to the top state.
   14810             switch (procState) {
   14811                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
   14812                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
   14813                 case ActivityManager.PROCESS_STATE_SERVICE:
   14814                     // These all are longer-term states, so pull them up to the top
   14815                     // of the background states, but not all the way to the top state.
   14816                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
   14817                     break;
   14818                 default:
   14819                     // Otherwise, top is a better choice, so take it.
   14820                     procState = ActivityManager.PROCESS_STATE_TOP;
   14821                     break;
   14822             }
   14823         }
   14824 
   14825         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
   14826             // This is a cached process, but with client activities.  Mark it so.
   14827             procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
   14828             app.adjType = "cch-client-act";
   14829         }
   14830 
   14831         if (adj == ProcessList.SERVICE_ADJ) {
   14832             if (doingAll) {
   14833                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
   14834                 mNewNumServiceProcs++;
   14835                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
   14836                 if (!app.serviceb) {
   14837                     // This service isn't far enough down on the LRU list to
   14838                     // normally be a B service, but if we are low on RAM and it
   14839                     // is large we want to force it down since we would prefer to
   14840                     // keep launcher over it.
   14841                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
   14842                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
   14843                         app.serviceHighRam = true;
   14844                         app.serviceb = true;
   14845                         //Slog.i(TAG, "ADJ " + app + " high ram!");
   14846                     } else {
   14847                         mNewNumAServiceProcs++;
   14848                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
   14849                     }
   14850                 } else {
   14851                     app.serviceHighRam = false;
   14852                 }
   14853             }
   14854             if (app.serviceb) {
   14855                 adj = ProcessList.SERVICE_B_ADJ;
   14856             }
   14857         }
   14858 
   14859         app.curRawAdj = adj;
   14860 
   14861         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
   14862         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
   14863         if (adj > app.maxAdj) {
   14864             adj = app.maxAdj;
   14865             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14866                 schedGroup = Process.THREAD_GROUP_DEFAULT;
   14867             }
   14868         }
   14869         if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
   14870             app.keeping = true;
   14871         }
   14872 
   14873         // Do final modification to adj.  Everything we do between here and applying
   14874         // the final setAdj must be done in this function, because we will also use
   14875         // it when computing the final cached adj later.  Note that we don't need to
   14876         // worry about this for max adj above, since max adj will always be used to
   14877         // keep it out of the cached vaues.
   14878         adj = app.modifyRawOomAdj(adj);
   14879 
   14880         app.curProcState = procState;
   14881 
   14882         int importance = app.memImportance;
   14883         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
   14884             app.curAdj = adj;
   14885             app.curSchedGroup = schedGroup;
   14886             if (!interesting) {
   14887                 // For this reporting, if there is not something explicitly
   14888                 // interesting in this process then we will push it to the
   14889                 // background importance.
   14890                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14891             } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
   14892                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14893             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
   14894                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14895             } else if (adj >= ProcessList.HOME_APP_ADJ) {
   14896                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
   14897             } else if (adj >= ProcessList.SERVICE_ADJ) {
   14898                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
   14899             } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
   14900                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
   14901             } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
   14902                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
   14903             } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
   14904                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
   14905             } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
   14906                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
   14907             } else {
   14908                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
   14909             }
   14910         }
   14911 
   14912         int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
   14913         if (foregroundActivities != app.foregroundActivities) {
   14914             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
   14915         }
   14916         if (changes != 0) {
   14917             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
   14918             app.memImportance = importance;
   14919             app.foregroundActivities = foregroundActivities;
   14920             int i = mPendingProcessChanges.size()-1;
   14921             ProcessChangeItem item = null;
   14922             while (i >= 0) {
   14923                 item = mPendingProcessChanges.get(i);
   14924                 if (item.pid == app.pid) {
   14925                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
   14926                     break;
   14927                 }
   14928                 i--;
   14929             }
   14930             if (i < 0) {
   14931                 // No existing item in pending changes; need a new one.
   14932                 final int NA = mAvailProcessChanges.size();
   14933                 if (NA > 0) {
   14934                     item = mAvailProcessChanges.remove(NA-1);
   14935                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
   14936                 } else {
   14937                     item = new ProcessChangeItem();
   14938                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
   14939                 }
   14940                 item.changes = 0;
   14941                 item.pid = app.pid;
   14942                 item.uid = app.info.uid;
   14943                 if (mPendingProcessChanges.size() == 0) {
   14944                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
   14945                             "*** Enqueueing dispatch processes changed!");
   14946                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
   14947                 }
   14948                 mPendingProcessChanges.add(item);
   14949             }
   14950             item.changes |= changes;
   14951             item.importance = importance;
   14952             item.foregroundActivities = foregroundActivities;
   14953             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
   14954                     + Integer.toHexString(System.identityHashCode(item))
   14955                     + " " + app.toShortString() + ": changes=" + item.changes
   14956                     + " importance=" + item.importance
   14957                     + " foreground=" + item.foregroundActivities
   14958                     + " type=" + app.adjType + " source=" + app.adjSource
   14959                     + " target=" + app.adjTarget);
   14960         }
   14961 
   14962         return app.curRawAdj;
   14963     }
   14964 
   14965     /**
   14966      * Schedule PSS collection of a process.
   14967      */
   14968     void requestPssLocked(ProcessRecord proc, int procState) {
   14969         if (mPendingPssProcesses.contains(proc)) {
   14970             return;
   14971         }
   14972         if (mPendingPssProcesses.size() == 0) {
   14973             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   14974         }
   14975         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
   14976         proc.pssProcState = procState;
   14977         mPendingPssProcesses.add(proc);
   14978     }
   14979 
   14980     /**
   14981      * Schedule PSS collection of all processes.
   14982      */
   14983     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
   14984         if (!always) {
   14985             if (now < (mLastFullPssTime +
   14986                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
   14987                 return;
   14988             }
   14989         }
   14990         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
   14991         mLastFullPssTime = now;
   14992         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
   14993         mPendingPssProcesses.clear();
   14994         for (int i=mLruProcesses.size()-1; i>=0; i--) {
   14995             ProcessRecord app = mLruProcesses.get(i);
   14996             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
   14997                 app.pssProcState = app.setProcState;
   14998                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   14999                         mSleeping, now);
   15000                 mPendingPssProcesses.add(app);
   15001             }
   15002         }
   15003         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
   15004     }
   15005 
   15006     /**
   15007      * Ask a given process to GC right now.
   15008      */
   15009     final void performAppGcLocked(ProcessRecord app) {
   15010         try {
   15011             app.lastRequestedGc = SystemClock.uptimeMillis();
   15012             if (app.thread != null) {
   15013                 if (app.reportLowMemory) {
   15014                     app.reportLowMemory = false;
   15015                     app.thread.scheduleLowMemory();
   15016                 } else {
   15017                     app.thread.processInBackground();
   15018                 }
   15019             }
   15020         } catch (Exception e) {
   15021             // whatever.
   15022         }
   15023     }
   15024 
   15025     /**
   15026      * Returns true if things are idle enough to perform GCs.
   15027      */
   15028     private final boolean canGcNowLocked() {
   15029         boolean processingBroadcasts = false;
   15030         for (BroadcastQueue q : mBroadcastQueues) {
   15031             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
   15032                 processingBroadcasts = true;
   15033             }
   15034         }
   15035         return !processingBroadcasts
   15036                 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
   15037     }
   15038 
   15039     /**
   15040      * Perform GCs on all processes that are waiting for it, but only
   15041      * if things are idle.
   15042      */
   15043     final void performAppGcsLocked() {
   15044         final int N = mProcessesToGc.size();
   15045         if (N <= 0) {
   15046             return;
   15047         }
   15048         if (canGcNowLocked()) {
   15049             while (mProcessesToGc.size() > 0) {
   15050                 ProcessRecord proc = mProcessesToGc.remove(0);
   15051                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
   15052                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
   15053                             <= SystemClock.uptimeMillis()) {
   15054                         // To avoid spamming the system, we will GC processes one
   15055                         // at a time, waiting a few seconds between each.
   15056                         performAppGcLocked(proc);
   15057                         scheduleAppGcsLocked();
   15058                         return;
   15059                     } else {
   15060                         // It hasn't been long enough since we last GCed this
   15061                         // process...  put it in the list to wait for its time.
   15062                         addProcessToGcListLocked(proc);
   15063                         break;
   15064                     }
   15065                 }
   15066             }
   15067 
   15068             scheduleAppGcsLocked();
   15069         }
   15070     }
   15071 
   15072     /**
   15073      * If all looks good, perform GCs on all processes waiting for them.
   15074      */
   15075     final void performAppGcsIfAppropriateLocked() {
   15076         if (canGcNowLocked()) {
   15077             performAppGcsLocked();
   15078             return;
   15079         }
   15080         // Still not idle, wait some more.
   15081         scheduleAppGcsLocked();
   15082     }
   15083 
   15084     /**
   15085      * Schedule the execution of all pending app GCs.
   15086      */
   15087     final void scheduleAppGcsLocked() {
   15088         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
   15089 
   15090         if (mProcessesToGc.size() > 0) {
   15091             // Schedule a GC for the time to the next process.
   15092             ProcessRecord proc = mProcessesToGc.get(0);
   15093             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
   15094 
   15095             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
   15096             long now = SystemClock.uptimeMillis();
   15097             if (when < (now+GC_TIMEOUT)) {
   15098                 when = now + GC_TIMEOUT;
   15099             }
   15100             mHandler.sendMessageAtTime(msg, when);
   15101         }
   15102     }
   15103 
   15104     /**
   15105      * Add a process to the array of processes waiting to be GCed.  Keeps the
   15106      * list in sorted order by the last GC time.  The process can't already be
   15107      * on the list.
   15108      */
   15109     final void addProcessToGcListLocked(ProcessRecord proc) {
   15110         boolean added = false;
   15111         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
   15112             if (mProcessesToGc.get(i).lastRequestedGc <
   15113                     proc.lastRequestedGc) {
   15114                 added = true;
   15115                 mProcessesToGc.add(i+1, proc);
   15116                 break;
   15117             }
   15118         }
   15119         if (!added) {
   15120             mProcessesToGc.add(0, proc);
   15121         }
   15122     }
   15123 
   15124     /**
   15125      * Set up to ask a process to GC itself.  This will either do it
   15126      * immediately, or put it on the list of processes to gc the next
   15127      * time things are idle.
   15128      */
   15129     final void scheduleAppGcLocked(ProcessRecord app) {
   15130         long now = SystemClock.uptimeMillis();
   15131         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
   15132             return;
   15133         }
   15134         if (!mProcessesToGc.contains(app)) {
   15135             addProcessToGcListLocked(app);
   15136             scheduleAppGcsLocked();
   15137         }
   15138     }
   15139 
   15140     final void checkExcessivePowerUsageLocked(boolean doKills) {
   15141         updateCpuStatsNow();
   15142 
   15143         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15144         boolean doWakeKills = doKills;
   15145         boolean doCpuKills = doKills;
   15146         if (mLastPowerCheckRealtime == 0) {
   15147             doWakeKills = false;
   15148         }
   15149         if (mLastPowerCheckUptime == 0) {
   15150             doCpuKills = false;
   15151         }
   15152         if (stats.isScreenOn()) {
   15153             doWakeKills = false;
   15154         }
   15155         final long curRealtime = SystemClock.elapsedRealtime();
   15156         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
   15157         final long curUptime = SystemClock.uptimeMillis();
   15158         final long uptimeSince = curUptime - mLastPowerCheckUptime;
   15159         mLastPowerCheckRealtime = curRealtime;
   15160         mLastPowerCheckUptime = curUptime;
   15161         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
   15162             doWakeKills = false;
   15163         }
   15164         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
   15165             doCpuKills = false;
   15166         }
   15167         int i = mLruProcesses.size();
   15168         while (i > 0) {
   15169             i--;
   15170             ProcessRecord app = mLruProcesses.get(i);
   15171             if (!app.keeping) {
   15172                 long wtime;
   15173                 synchronized (stats) {
   15174                     wtime = stats.getProcessWakeTime(app.info.uid,
   15175                             app.pid, curRealtime);
   15176                 }
   15177                 long wtimeUsed = wtime - app.lastWakeTime;
   15178                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
   15179                 if (DEBUG_POWER) {
   15180                     StringBuilder sb = new StringBuilder(128);
   15181                     sb.append("Wake for ");
   15182                     app.toShortString(sb);
   15183                     sb.append(": over ");
   15184                     TimeUtils.formatDuration(realtimeSince, sb);
   15185                     sb.append(" used ");
   15186                     TimeUtils.formatDuration(wtimeUsed, sb);
   15187                     sb.append(" (");
   15188                     sb.append((wtimeUsed*100)/realtimeSince);
   15189                     sb.append("%)");
   15190                     Slog.i(TAG, sb.toString());
   15191                     sb.setLength(0);
   15192                     sb.append("CPU for ");
   15193                     app.toShortString(sb);
   15194                     sb.append(": over ");
   15195                     TimeUtils.formatDuration(uptimeSince, sb);
   15196                     sb.append(" used ");
   15197                     TimeUtils.formatDuration(cputimeUsed, sb);
   15198                     sb.append(" (");
   15199                     sb.append((cputimeUsed*100)/uptimeSince);
   15200                     sb.append("%)");
   15201                     Slog.i(TAG, sb.toString());
   15202                 }
   15203                 // If a process has held a wake lock for more
   15204                 // than 50% of the time during this period,
   15205                 // that sounds bad.  Kill!
   15206                 if (doWakeKills && realtimeSince > 0
   15207                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
   15208                     synchronized (stats) {
   15209                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
   15210                                 realtimeSince, wtimeUsed);
   15211                     }
   15212                     killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
   15213                             + " during " + realtimeSince);
   15214                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
   15215                 } else if (doCpuKills && uptimeSince > 0
   15216                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
   15217                     synchronized (stats) {
   15218                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
   15219                                 uptimeSince, cputimeUsed);
   15220                     }
   15221                     killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
   15222                             + " during " + uptimeSince);
   15223                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
   15224                 } else {
   15225                     app.lastWakeTime = wtime;
   15226                     app.lastCpuTime = app.curCpuTime;
   15227                 }
   15228             }
   15229         }
   15230     }
   15231 
   15232     private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
   15233             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15234         boolean success = true;
   15235 
   15236         if (app.curRawAdj != app.setRawAdj) {
   15237             if (wasKeeping && !app.keeping) {
   15238                 // This app is no longer something we want to keep.  Note
   15239                 // its current wake lock time to later know to kill it if
   15240                 // it is not behaving well.
   15241                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
   15242                 synchronized (stats) {
   15243                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
   15244                             app.pid, SystemClock.elapsedRealtime());
   15245                 }
   15246                 app.lastCpuTime = app.curCpuTime;
   15247             }
   15248 
   15249             app.setRawAdj = app.curRawAdj;
   15250         }
   15251 
   15252         if (app.curAdj != app.setAdj) {
   15253             if (Process.setOomAdj(app.pid, app.curAdj)) {
   15254                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
   15255                     TAG, "Set " + app.pid + " " + app.processName +
   15256                     " adj " + app.curAdj + ": " + app.adjType);
   15257                 app.setAdj = app.curAdj;
   15258             } else {
   15259                 success = false;
   15260                 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
   15261             }
   15262         }
   15263         if (app.setSchedGroup != app.curSchedGroup) {
   15264             app.setSchedGroup = app.curSchedGroup;
   15265             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15266                     "Setting process group of " + app.processName
   15267                     + " to " + app.curSchedGroup);
   15268             if (app.waitingToKill != null &&
   15269                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
   15270                 killUnneededProcessLocked(app, app.waitingToKill);
   15271                 success = false;
   15272             } else {
   15273                 if (true) {
   15274                     long oldId = Binder.clearCallingIdentity();
   15275                     try {
   15276                         Process.setProcessGroup(app.pid, app.curSchedGroup);
   15277                     } catch (Exception e) {
   15278                         Slog.w(TAG, "Failed setting process group of " + app.pid
   15279                                 + " to " + app.curSchedGroup);
   15280                         e.printStackTrace();
   15281                     } finally {
   15282                         Binder.restoreCallingIdentity(oldId);
   15283                     }
   15284                 } else {
   15285                     if (app.thread != null) {
   15286                         try {
   15287                             app.thread.setSchedulingGroup(app.curSchedGroup);
   15288                         } catch (RemoteException e) {
   15289                         }
   15290                     }
   15291                 }
   15292                 Process.setSwappiness(app.pid,
   15293                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
   15294             }
   15295         }
   15296         if (app.repProcState != app.curProcState) {
   15297             app.repProcState = app.curProcState;
   15298             if (!reportingProcessState && app.thread != null) {
   15299                 try {
   15300                     if (false) {
   15301                         //RuntimeException h = new RuntimeException("here");
   15302                         Slog.i(TAG, "Sending new process state " + app.repProcState
   15303                                 + " to " + app /*, h*/);
   15304                     }
   15305                     app.thread.setProcessState(app.repProcState);
   15306                 } catch (RemoteException e) {
   15307                 }
   15308             }
   15309         }
   15310         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
   15311                 app.setProcState)) {
   15312             app.lastStateTime = now;
   15313             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
   15314                     mSleeping, now);
   15315             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
   15316                     + ProcessList.makeProcStateString(app.setProcState) + " to "
   15317                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
   15318                     + (app.nextPssTime-now) + ": " + app);
   15319         } else {
   15320             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
   15321                     && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
   15322                 requestPssLocked(app, app.setProcState);
   15323                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
   15324                         mSleeping, now);
   15325             } else if (false && DEBUG_PSS) {
   15326                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
   15327             }
   15328         }
   15329         if (app.setProcState != app.curProcState) {
   15330             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15331                     "Proc state change of " + app.processName
   15332                     + " to " + app.curProcState);
   15333             app.setProcState = app.curProcState;
   15334             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
   15335                 app.notCachedSinceIdle = false;
   15336             }
   15337             if (!doingAll) {
   15338                 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
   15339             } else {
   15340                 app.procStateChanged = true;
   15341             }
   15342         }
   15343         return success;
   15344     }
   15345 
   15346     private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
   15347         if (proc.thread != null && proc.baseProcessTracker != null) {
   15348             proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
   15349         }
   15350     }
   15351 
   15352     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
   15353             ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
   15354         if (app.thread == null) {
   15355             return false;
   15356         }
   15357 
   15358         final boolean wasKeeping = app.keeping;
   15359 
   15360         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
   15361 
   15362         return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
   15363                 reportingProcessState, now);
   15364     }
   15365 
   15366     private final ActivityRecord resumedAppLocked() {
   15367         return mStackSupervisor.resumedAppLocked();
   15368     }
   15369 
   15370     final boolean updateOomAdjLocked(ProcessRecord app) {
   15371         return updateOomAdjLocked(app, false);
   15372     }
   15373 
   15374     final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
   15375         final ActivityRecord TOP_ACT = resumedAppLocked();
   15376         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15377         final boolean wasCached = app.cached;
   15378 
   15379         mAdjSeq++;
   15380 
   15381         // This is the desired cached adjusment we want to tell it to use.
   15382         // If our app is currently cached, we know it, and that is it.  Otherwise,
   15383         // we don't know it yet, and it needs to now be cached we will then
   15384         // need to do a complete oom adj.
   15385         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
   15386                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
   15387         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
   15388                 SystemClock.uptimeMillis());
   15389         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
   15390             // Changed to/from cached state, so apps after it in the LRU
   15391             // list may also be changed.
   15392             updateOomAdjLocked();
   15393         }
   15394         return success;
   15395     }
   15396 
   15397     final void updateOomAdjLocked() {
   15398         final ActivityRecord TOP_ACT = resumedAppLocked();
   15399         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
   15400         final long now = SystemClock.uptimeMillis();
   15401         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
   15402         final int N = mLruProcesses.size();
   15403 
   15404         if (false) {
   15405             RuntimeException e = new RuntimeException();
   15406             e.fillInStackTrace();
   15407             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
   15408         }
   15409 
   15410         mAdjSeq++;
   15411         mNewNumServiceProcs = 0;
   15412         mNewNumAServiceProcs = 0;
   15413 
   15414         final int emptyProcessLimit;
   15415         final int cachedProcessLimit;
   15416         if (mProcessLimit <= 0) {
   15417             emptyProcessLimit = cachedProcessLimit = 0;
   15418         } else if (mProcessLimit == 1) {
   15419             emptyProcessLimit = 1;
   15420             cachedProcessLimit = 0;
   15421         } else {
   15422             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
   15423             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
   15424         }
   15425 
   15426         // Let's determine how many processes we have running vs.
   15427         // how many slots we have for background processes; we may want
   15428         // to put multiple processes in a slot of there are enough of
   15429         // them.
   15430         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
   15431                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
   15432         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
   15433         if (numEmptyProcs > cachedProcessLimit) {
   15434             // If there are more empty processes than our limit on cached
   15435             // processes, then use the cached process limit for the factor.
   15436             // This ensures that the really old empty processes get pushed
   15437             // down to the bottom, so if we are running low on memory we will
   15438             // have a better chance at keeping around more cached processes
   15439             // instead of a gazillion empty processes.
   15440             numEmptyProcs = cachedProcessLimit;
   15441         }
   15442         int emptyFactor = numEmptyProcs/numSlots;
   15443         if (emptyFactor < 1) emptyFactor = 1;
   15444         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
   15445         if (cachedFactor < 1) cachedFactor = 1;
   15446         int stepCached = 0;
   15447         int stepEmpty = 0;
   15448         int numCached = 0;
   15449         int numEmpty = 0;
   15450         int numTrimming = 0;
   15451 
   15452         mNumNonCachedProcs = 0;
   15453         mNumCachedHiddenProcs = 0;
   15454 
   15455         // First update the OOM adjustment for each of the
   15456         // application processes based on their current state.
   15457         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15458         int nextCachedAdj = curCachedAdj+1;
   15459         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
   15460         int nextEmptyAdj = curEmptyAdj+2;
   15461         for (int i=N-1; i>=0; i--) {
   15462             ProcessRecord app = mLruProcesses.get(i);
   15463             if (!app.killedByAm && app.thread != null) {
   15464                 app.procStateChanged = false;
   15465                 final boolean wasKeeping = app.keeping;
   15466                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
   15467 
   15468                 // If we haven't yet assigned the final cached adj
   15469                 // to the process, do that now.
   15470                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
   15471                     switch (app.curProcState) {
   15472                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15473                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15474                             // This process is a cached process holding activities...
   15475                             // assign it the next cached value for that type, and then
   15476                             // step that cached level.
   15477                             app.curRawAdj = curCachedAdj;
   15478                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
   15479                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
   15480                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
   15481                                     + ")");
   15482                             if (curCachedAdj != nextCachedAdj) {
   15483                                 stepCached++;
   15484                                 if (stepCached >= cachedFactor) {
   15485                                     stepCached = 0;
   15486                                     curCachedAdj = nextCachedAdj;
   15487                                     nextCachedAdj += 2;
   15488                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15489                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15490                                     }
   15491                                 }
   15492                             }
   15493                             break;
   15494                         default:
   15495                             // For everything else, assign next empty cached process
   15496                             // level and bump that up.  Note that this means that
   15497                             // long-running services that have dropped down to the
   15498                             // cached level will be treated as empty (since their process
   15499                             // state is still as a service), which is what we want.
   15500                             app.curRawAdj = curEmptyAdj;
   15501                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
   15502                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
   15503                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
   15504                                     + ")");
   15505                             if (curEmptyAdj != nextEmptyAdj) {
   15506                                 stepEmpty++;
   15507                                 if (stepEmpty >= emptyFactor) {
   15508                                     stepEmpty = 0;
   15509                                     curEmptyAdj = nextEmptyAdj;
   15510                                     nextEmptyAdj += 2;
   15511                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
   15512                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
   15513                                     }
   15514                                 }
   15515                             }
   15516                             break;
   15517                     }
   15518                 }
   15519 
   15520                 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
   15521 
   15522                 // Count the number of process types.
   15523                 switch (app.curProcState) {
   15524                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
   15525                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
   15526                         mNumCachedHiddenProcs++;
   15527                         numCached++;
   15528                         if (numCached > cachedProcessLimit) {
   15529                             killUnneededProcessLocked(app, "cached #" + numCached);
   15530                         }
   15531                         break;
   15532                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
   15533                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
   15534                                 && app.lastActivityTime < oldTime) {
   15535                             killUnneededProcessLocked(app, "empty for "
   15536                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
   15537                                     / 1000) + "s");
   15538                         } else {
   15539                             numEmpty++;
   15540                             if (numEmpty > emptyProcessLimit) {
   15541                                 killUnneededProcessLocked(app, "empty #" + numEmpty);
   15542                             }
   15543                         }
   15544                         break;
   15545                     default:
   15546                         mNumNonCachedProcs++;
   15547                         break;
   15548                 }
   15549 
   15550                 if (app.isolated && app.services.size() <= 0) {
   15551                     // If this is an isolated process, and there are no
   15552                     // services running in it, then the process is no longer
   15553                     // needed.  We agressively kill these because we can by
   15554                     // definition not re-use the same process again, and it is
   15555                     // good to avoid having whatever code was running in them
   15556                     // left sitting around after no longer needed.
   15557                     killUnneededProcessLocked(app, "isolated not needed");
   15558                 }
   15559 
   15560                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15561                         && !app.killedByAm) {
   15562                     numTrimming++;
   15563                 }
   15564             }
   15565         }
   15566 
   15567         mNumServiceProcs = mNewNumServiceProcs;
   15568 
   15569         // Now determine the memory trimming level of background processes.
   15570         // Unfortunately we need to start at the back of the list to do this
   15571         // properly.  We only do this if the number of background apps we
   15572         // are managing to keep around is less than half the maximum we desire;
   15573         // if we are keeping a good number around, we'll let them use whatever
   15574         // memory they want.
   15575         final int numCachedAndEmpty = numCached + numEmpty;
   15576         int memFactor;
   15577         if (numCached <= ProcessList.TRIM_CACHED_APPS
   15578                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
   15579             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
   15580                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
   15581             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
   15582                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
   15583             } else {
   15584                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
   15585             }
   15586         } else {
   15587             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
   15588         }
   15589         // We always allow the memory level to go up (better).  We only allow it to go
   15590         // down if we are in a state where that is allowed, *and* the total number of processes
   15591         // has gone down since last time.
   15592         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
   15593                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
   15594                 + " last=" + mLastNumProcesses);
   15595         if (memFactor > mLastMemoryLevel) {
   15596             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
   15597                 memFactor = mLastMemoryLevel;
   15598                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
   15599             }
   15600         }
   15601         mLastMemoryLevel = memFactor;
   15602         mLastNumProcesses = mLruProcesses.size();
   15603         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
   15604         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
   15605         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
   15606             if (mLowRamStartTime == 0) {
   15607                 mLowRamStartTime = now;
   15608             }
   15609             int step = 0;
   15610             int fgTrimLevel;
   15611             switch (memFactor) {
   15612                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
   15613                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
   15614                     break;
   15615                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
   15616                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
   15617                     break;
   15618                 default:
   15619                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
   15620                     break;
   15621             }
   15622             int factor = numTrimming/3;
   15623             int minFactor = 2;
   15624             if (mHomeProcess != null) minFactor++;
   15625             if (mPreviousProcess != null) minFactor++;
   15626             if (factor < minFactor) factor = minFactor;
   15627             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
   15628             for (int i=N-1; i>=0; i--) {
   15629                 ProcessRecord app = mLruProcesses.get(i);
   15630                 if (allChanged || app.procStateChanged) {
   15631                     setProcessTrackerState(app, trackerMemFactor, now);
   15632                     app.procStateChanged = false;
   15633                 }
   15634                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
   15635                         && !app.killedByAm) {
   15636                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
   15637                         try {
   15638                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15639                                     "Trimming memory of " + app.processName
   15640                                     + " to " + curLevel);
   15641                             app.thread.scheduleTrimMemory(curLevel);
   15642                         } catch (RemoteException e) {
   15643                         }
   15644                         if (false) {
   15645                             // For now we won't do this; our memory trimming seems
   15646                             // to be good enough at this point that destroying
   15647                             // activities causes more harm than good.
   15648                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
   15649                                     && app != mHomeProcess && app != mPreviousProcess) {
   15650                                 // Need to do this on its own message because the stack may not
   15651                                 // be in a consistent state at this point.
   15652                                 // For these apps we will also finish their activities
   15653                                 // to help them free memory.
   15654                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   15655                             }
   15656                         }
   15657                     }
   15658                     app.trimMemoryLevel = curLevel;
   15659                     step++;
   15660                     if (step >= factor) {
   15661                         step = 0;
   15662                         switch (curLevel) {
   15663                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
   15664                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
   15665                                 break;
   15666                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
   15667                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15668                                 break;
   15669                         }
   15670                     }
   15671                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
   15672                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
   15673                             && app.thread != null) {
   15674                         try {
   15675                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15676                                     "Trimming memory of heavy-weight " + app.processName
   15677                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15678                             app.thread.scheduleTrimMemory(
   15679                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
   15680                         } catch (RemoteException e) {
   15681                         }
   15682                     }
   15683                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
   15684                 } else {
   15685                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15686                             || app.systemNoUi) && app.pendingUiClean) {
   15687                         // If this application is now in the background and it
   15688                         // had done UI, then give it the special trim level to
   15689                         // have it free UI resources.
   15690                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
   15691                         if (app.trimMemoryLevel < level && app.thread != null) {
   15692                             try {
   15693                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15694                                         "Trimming memory of bg-ui " + app.processName
   15695                                         + " to " + level);
   15696                                 app.thread.scheduleTrimMemory(level);
   15697                             } catch (RemoteException e) {
   15698                             }
   15699                         }
   15700                         app.pendingUiClean = false;
   15701                     }
   15702                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
   15703                         try {
   15704                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15705                                     "Trimming memory of fg " + app.processName
   15706                                     + " to " + fgTrimLevel);
   15707                             app.thread.scheduleTrimMemory(fgTrimLevel);
   15708                         } catch (RemoteException e) {
   15709                         }
   15710                     }
   15711                     app.trimMemoryLevel = fgTrimLevel;
   15712                 }
   15713             }
   15714         } else {
   15715             if (mLowRamStartTime != 0) {
   15716                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
   15717                 mLowRamStartTime = 0;
   15718             }
   15719             for (int i=N-1; i>=0; i--) {
   15720                 ProcessRecord app = mLruProcesses.get(i);
   15721                 if (allChanged || app.procStateChanged) {
   15722                     setProcessTrackerState(app, trackerMemFactor, now);
   15723                     app.procStateChanged = false;
   15724                 }
   15725                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
   15726                         || app.systemNoUi) && app.pendingUiClean) {
   15727                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
   15728                             && app.thread != null) {
   15729                         try {
   15730                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
   15731                                     "Trimming memory of ui hidden " + app.processName
   15732                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15733                             app.thread.scheduleTrimMemory(
   15734                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
   15735                         } catch (RemoteException e) {
   15736                         }
   15737                     }
   15738                     app.pendingUiClean = false;
   15739                 }
   15740                 app.trimMemoryLevel = 0;
   15741             }
   15742         }
   15743 
   15744         if (mAlwaysFinishActivities) {
   15745             // Need to do this on its own message because the stack may not
   15746             // be in a consistent state at this point.
   15747             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
   15748         }
   15749 
   15750         if (allChanged) {
   15751             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
   15752         }
   15753 
   15754         if (mProcessStats.shouldWriteNowLocked(now)) {
   15755             mHandler.post(new Runnable() {
   15756                 @Override public void run() {
   15757                     synchronized (ActivityManagerService.this) {
   15758                         mProcessStats.writeStateAsyncLocked();
   15759                     }
   15760                 }
   15761             });
   15762         }
   15763 
   15764         if (DEBUG_OOM_ADJ) {
   15765             Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
   15766         }
   15767     }
   15768 
   15769     final void trimApplications() {
   15770         synchronized (this) {
   15771             int i;
   15772 
   15773             // First remove any unused application processes whose package
   15774             // has been removed.
   15775             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
   15776                 final ProcessRecord app = mRemovedProcesses.get(i);
   15777                 if (app.activities.size() == 0
   15778                         && app.curReceiver == null && app.services.size() == 0) {
   15779                     Slog.i(
   15780                         TAG, "Exiting empty application process "
   15781                         + app.processName + " ("
   15782                         + (app.thread != null ? app.thread.asBinder() : null)
   15783                         + ")\n");
   15784                     if (app.pid > 0 && app.pid != MY_PID) {
   15785                         EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
   15786                                 app.processName, app.setAdj, "empty");
   15787                         app.killedByAm = true;
   15788                         Process.killProcessQuiet(app.pid);
   15789                     } else {
   15790                         try {
   15791                             app.thread.scheduleExit();
   15792                         } catch (Exception e) {
   15793                             // Ignore exceptions.
   15794                         }
   15795                     }
   15796                     cleanUpApplicationRecordLocked(app, false, true, -1);
   15797                     mRemovedProcesses.remove(i);
   15798 
   15799                     if (app.persistent) {
   15800                         if (app.persistent) {
   15801                             addAppLocked(app.info, false);
   15802                         }
   15803                     }
   15804                 }
   15805             }
   15806 
   15807             // Now update the oom adj for all processes.
   15808             updateOomAdjLocked();
   15809         }
   15810     }
   15811 
   15812     /** This method sends the specified signal to each of the persistent apps */
   15813     public void signalPersistentProcesses(int sig) throws RemoteException {
   15814         if (sig != Process.SIGNAL_USR1) {
   15815             throw new SecurityException("Only SIGNAL_USR1 is allowed");
   15816         }
   15817 
   15818         synchronized (this) {
   15819             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
   15820                     != PackageManager.PERMISSION_GRANTED) {
   15821                 throw new SecurityException("Requires permission "
   15822                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
   15823             }
   15824 
   15825             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
   15826                 ProcessRecord r = mLruProcesses.get(i);
   15827                 if (r.thread != null && r.persistent) {
   15828                     Process.sendSignal(r.pid, sig);
   15829                 }
   15830             }
   15831         }
   15832     }
   15833 
   15834     private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
   15835         if (proc == null || proc == mProfileProc) {
   15836             proc = mProfileProc;
   15837             path = mProfileFile;
   15838             profileType = mProfileType;
   15839             clearProfilerLocked();
   15840         }
   15841         if (proc == null) {
   15842             return;
   15843         }
   15844         try {
   15845             proc.thread.profilerControl(false, path, null, profileType);
   15846         } catch (RemoteException e) {
   15847             throw new IllegalStateException("Process disappeared");
   15848         }
   15849     }
   15850 
   15851     private void clearProfilerLocked() {
   15852         if (mProfileFd != null) {
   15853             try {
   15854                 mProfileFd.close();
   15855             } catch (IOException e) {
   15856             }
   15857         }
   15858         mProfileApp = null;
   15859         mProfileProc = null;
   15860         mProfileFile = null;
   15861         mProfileType = 0;
   15862         mAutoStopProfiler = false;
   15863     }
   15864 
   15865     public boolean profileControl(String process, int userId, boolean start,
   15866             String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
   15867 
   15868         try {
   15869             synchronized (this) {
   15870                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15871                 // its own permission.
   15872                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15873                         != PackageManager.PERMISSION_GRANTED) {
   15874                     throw new SecurityException("Requires permission "
   15875                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15876                 }
   15877 
   15878                 if (start && fd == null) {
   15879                     throw new IllegalArgumentException("null fd");
   15880                 }
   15881 
   15882                 ProcessRecord proc = null;
   15883                 if (process != null) {
   15884                     proc = findProcessLocked(process, userId, "profileControl");
   15885                 }
   15886 
   15887                 if (start && (proc == null || proc.thread == null)) {
   15888                     throw new IllegalArgumentException("Unknown process: " + process);
   15889                 }
   15890 
   15891                 if (start) {
   15892                     stopProfilerLocked(null, null, 0);
   15893                     setProfileApp(proc.info, proc.processName, path, fd, false);
   15894                     mProfileProc = proc;
   15895                     mProfileType = profileType;
   15896                     try {
   15897                         fd = fd.dup();
   15898                     } catch (IOException e) {
   15899                         fd = null;
   15900                     }
   15901                     proc.thread.profilerControl(start, path, fd, profileType);
   15902                     fd = null;
   15903                     mProfileFd = null;
   15904                 } else {
   15905                     stopProfilerLocked(proc, path, profileType);
   15906                     if (fd != null) {
   15907                         try {
   15908                             fd.close();
   15909                         } catch (IOException e) {
   15910                         }
   15911                     }
   15912                 }
   15913 
   15914                 return true;
   15915             }
   15916         } catch (RemoteException e) {
   15917             throw new IllegalStateException("Process disappeared");
   15918         } finally {
   15919             if (fd != null) {
   15920                 try {
   15921                     fd.close();
   15922                 } catch (IOException e) {
   15923                 }
   15924             }
   15925         }
   15926     }
   15927 
   15928     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
   15929         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
   15930                 userId, true, true, callName, null);
   15931         ProcessRecord proc = null;
   15932         try {
   15933             int pid = Integer.parseInt(process);
   15934             synchronized (mPidsSelfLocked) {
   15935                 proc = mPidsSelfLocked.get(pid);
   15936             }
   15937         } catch (NumberFormatException e) {
   15938         }
   15939 
   15940         if (proc == null) {
   15941             ArrayMap<String, SparseArray<ProcessRecord>> all
   15942                     = mProcessNames.getMap();
   15943             SparseArray<ProcessRecord> procs = all.get(process);
   15944             if (procs != null && procs.size() > 0) {
   15945                 proc = procs.valueAt(0);
   15946                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
   15947                     for (int i=1; i<procs.size(); i++) {
   15948                         ProcessRecord thisProc = procs.valueAt(i);
   15949                         if (thisProc.userId == userId) {
   15950                             proc = thisProc;
   15951                             break;
   15952                         }
   15953                     }
   15954                 }
   15955             }
   15956         }
   15957 
   15958         return proc;
   15959     }
   15960 
   15961     public boolean dumpHeap(String process, int userId, boolean managed,
   15962             String path, ParcelFileDescriptor fd) throws RemoteException {
   15963 
   15964         try {
   15965             synchronized (this) {
   15966                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
   15967                 // its own permission (same as profileControl).
   15968                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
   15969                         != PackageManager.PERMISSION_GRANTED) {
   15970                     throw new SecurityException("Requires permission "
   15971                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
   15972                 }
   15973 
   15974                 if (fd == null) {
   15975                     throw new IllegalArgumentException("null fd");
   15976                 }
   15977 
   15978                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
   15979                 if (proc == null || proc.thread == null) {
   15980                     throw new IllegalArgumentException("Unknown process: " + process);
   15981                 }
   15982 
   15983                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   15984                 if (!isDebuggable) {
   15985                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
   15986                         throw new SecurityException("Process not debuggable: " + proc);
   15987                     }
   15988                 }
   15989 
   15990                 proc.thread.dumpHeap(managed, path, fd);
   15991                 fd = null;
   15992                 return true;
   15993             }
   15994         } catch (RemoteException e) {
   15995             throw new IllegalStateException("Process disappeared");
   15996         } finally {
   15997             if (fd != null) {
   15998                 try {
   15999                     fd.close();
   16000                 } catch (IOException e) {
   16001                 }
   16002             }
   16003         }
   16004     }
   16005 
   16006     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
   16007     public void monitor() {
   16008         synchronized (this) { }
   16009     }
   16010 
   16011     void onCoreSettingsChange(Bundle settings) {
   16012         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
   16013             ProcessRecord processRecord = mLruProcesses.get(i);
   16014             try {
   16015                 if (processRecord.thread != null) {
   16016                     processRecord.thread.setCoreSettings(settings);
   16017                 }
   16018             } catch (RemoteException re) {
   16019                 /* ignore */
   16020             }
   16021         }
   16022     }
   16023 
   16024     // Multi-user methods
   16025 
   16026     @Override
   16027     public boolean switchUser(final int userId) {
   16028         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16029                 != PackageManager.PERMISSION_GRANTED) {
   16030             String msg = "Permission Denial: switchUser() from pid="
   16031                     + Binder.getCallingPid()
   16032                     + ", uid=" + Binder.getCallingUid()
   16033                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16034             Slog.w(TAG, msg);
   16035             throw new SecurityException(msg);
   16036         }
   16037 
   16038         final long ident = Binder.clearCallingIdentity();
   16039         try {
   16040             synchronized (this) {
   16041                 final int oldUserId = mCurrentUserId;
   16042                 if (oldUserId == userId) {
   16043                     return true;
   16044                 }
   16045 
   16046                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
   16047                 if (userInfo == null) {
   16048                     Slog.w(TAG, "No user info for user #" + userId);
   16049                     return false;
   16050                 }
   16051 
   16052                 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
   16053                         R.anim.screen_user_enter);
   16054 
   16055                 boolean needStart = false;
   16056 
   16057                 // If the user we are switching to is not currently started, then
   16058                 // we need to start it now.
   16059                 if (mStartedUsers.get(userId) == null) {
   16060                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
   16061                     updateStartedUserArrayLocked();
   16062                     needStart = true;
   16063                 }
   16064 
   16065                 mCurrentUserId = userId;
   16066                 final Integer userIdInt = Integer.valueOf(userId);
   16067                 mUserLru.remove(userIdInt);
   16068                 mUserLru.add(userIdInt);
   16069 
   16070                 mWindowManager.setCurrentUser(userId);
   16071 
   16072                 // Once the internal notion of the active user has switched, we lock the device
   16073                 // with the option to show the user switcher on the keyguard.
   16074                 mWindowManager.lockNow(null);
   16075 
   16076                 final UserStartedState uss = mStartedUsers.get(userId);
   16077 
   16078                 // Make sure user is in the started state.  If it is currently
   16079                 // stopping, we need to knock that off.
   16080                 if (uss.mState == UserStartedState.STATE_STOPPING) {
   16081                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
   16082                     // so we can just fairly silently bring the user back from
   16083                     // the almost-dead.
   16084                     uss.mState = UserStartedState.STATE_RUNNING;
   16085                     updateStartedUserArrayLocked();
   16086                     needStart = true;
   16087                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
   16088                     // This means ACTION_SHUTDOWN has been sent, so we will
   16089                     // need to treat this as a new boot of the user.
   16090                     uss.mState = UserStartedState.STATE_BOOTING;
   16091                     updateStartedUserArrayLocked();
   16092                     needStart = true;
   16093                 }
   16094 
   16095                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
   16096                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   16097                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
   16098                         oldUserId, userId, uss));
   16099                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
   16100                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
   16101                 if (needStart) {
   16102                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
   16103                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16104                             | Intent.FLAG_RECEIVER_FOREGROUND);
   16105                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16106                     broadcastIntentLocked(null, null, intent,
   16107                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16108                             false, false, MY_PID, Process.SYSTEM_UID, userId);
   16109                 }
   16110 
   16111                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
   16112                     if (userId != 0) {
   16113                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
   16114                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   16115                         broadcastIntentLocked(null, null, intent, null,
   16116                                 new IIntentReceiver.Stub() {
   16117                                     public void performReceive(Intent intent, int resultCode,
   16118                                             String data, Bundle extras, boolean ordered,
   16119                                             boolean sticky, int sendingUser) {
   16120                                         userInitialized(uss, userId);
   16121                                     }
   16122                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
   16123                                 true, false, MY_PID, Process.SYSTEM_UID,
   16124                                 userId);
   16125                         uss.initializing = true;
   16126                     } else {
   16127                         getUserManagerLocked().makeInitialized(userInfo.id);
   16128                     }
   16129                 }
   16130 
   16131                 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
   16132                 if (homeInFront) {
   16133                     startHomeActivityLocked(userId);
   16134                 } else {
   16135                     mStackSupervisor.resumeTopActivitiesLocked();
   16136                 }
   16137 
   16138                 EventLogTags.writeAmSwitchUser(userId);
   16139                 getUserManagerLocked().userForeground(userId);
   16140                 sendUserSwitchBroadcastsLocked(oldUserId, userId);
   16141                 if (needStart) {
   16142                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
   16143                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16144                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16145                     broadcastIntentLocked(null, null, intent,
   16146                             null, new IIntentReceiver.Stub() {
   16147                                 @Override
   16148                                 public void performReceive(Intent intent, int resultCode, String data,
   16149                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
   16150                                         throws RemoteException {
   16151                                 }
   16152                             }, 0, null, null,
   16153                             android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   16154                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16155                 }
   16156             }
   16157         } finally {
   16158             Binder.restoreCallingIdentity(ident);
   16159         }
   16160 
   16161         return true;
   16162     }
   16163 
   16164     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
   16165         long ident = Binder.clearCallingIdentity();
   16166         try {
   16167             Intent intent;
   16168             if (oldUserId >= 0) {
   16169                 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
   16170                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16171                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16172                 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
   16173                 broadcastIntentLocked(null, null, intent,
   16174                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16175                         false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
   16176             }
   16177             if (newUserId >= 0) {
   16178                 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   16179                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16180                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16181                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   16182                 broadcastIntentLocked(null, null, intent,
   16183                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
   16184                         false, false, MY_PID, Process.SYSTEM_UID, newUserId);
   16185                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
   16186                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
   16187                         | Intent.FLAG_RECEIVER_FOREGROUND);
   16188                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
   16189                 broadcastIntentLocked(null, null, intent,
   16190                         null, null, 0, null, null,
   16191                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
   16192                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16193             }
   16194         } finally {
   16195             Binder.restoreCallingIdentity(ident);
   16196         }
   16197     }
   16198 
   16199     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
   16200             final int newUserId) {
   16201         final int N = mUserSwitchObservers.beginBroadcast();
   16202         if (N > 0) {
   16203             final IRemoteCallback callback = new IRemoteCallback.Stub() {
   16204                 int mCount = 0;
   16205                 @Override
   16206                 public void sendResult(Bundle data) throws RemoteException {
   16207                     synchronized (ActivityManagerService.this) {
   16208                         if (mCurUserSwitchCallback == this) {
   16209                             mCount++;
   16210                             if (mCount == N) {
   16211                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16212                             }
   16213                         }
   16214                     }
   16215                 }
   16216             };
   16217             synchronized (this) {
   16218                 uss.switching = true;
   16219                 mCurUserSwitchCallback = callback;
   16220             }
   16221             for (int i=0; i<N; i++) {
   16222                 try {
   16223                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
   16224                             newUserId, callback);
   16225                 } catch (RemoteException e) {
   16226                 }
   16227             }
   16228         } else {
   16229             synchronized (this) {
   16230                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16231             }
   16232         }
   16233         mUserSwitchObservers.finishBroadcast();
   16234     }
   16235 
   16236     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16237         synchronized (this) {
   16238             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
   16239             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
   16240         }
   16241     }
   16242 
   16243     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
   16244         mCurUserSwitchCallback = null;
   16245         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
   16246         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
   16247                 oldUserId, newUserId, uss));
   16248     }
   16249 
   16250     void userInitialized(UserStartedState uss, int newUserId) {
   16251         completeSwitchAndInitalize(uss, newUserId, true, false);
   16252     }
   16253 
   16254     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
   16255         completeSwitchAndInitalize(uss, newUserId, false, true);
   16256     }
   16257 
   16258     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
   16259             boolean clearInitializing, boolean clearSwitching) {
   16260         boolean unfrozen = false;
   16261         synchronized (this) {
   16262             if (clearInitializing) {
   16263                 uss.initializing = false;
   16264                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
   16265             }
   16266             if (clearSwitching) {
   16267                 uss.switching = false;
   16268             }
   16269             if (!uss.switching && !uss.initializing) {
   16270                 mWindowManager.stopFreezingScreen();
   16271                 unfrozen = true;
   16272             }
   16273         }
   16274         if (unfrozen) {
   16275             final int N = mUserSwitchObservers.beginBroadcast();
   16276             for (int i=0; i<N; i++) {
   16277                 try {
   16278                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
   16279                 } catch (RemoteException e) {
   16280                 }
   16281             }
   16282             mUserSwitchObservers.finishBroadcast();
   16283         }
   16284     }
   16285 
   16286     void finishUserSwitch(UserStartedState uss) {
   16287         synchronized (this) {
   16288             if (uss.mState == UserStartedState.STATE_BOOTING
   16289                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
   16290                 uss.mState = UserStartedState.STATE_RUNNING;
   16291                 final int userId = uss.mHandle.getIdentifier();
   16292                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
   16293                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16294                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
   16295                 broadcastIntentLocked(null, null, intent,
   16296                         null, null, 0, null, null,
   16297                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
   16298                         true, false, MY_PID, Process.SYSTEM_UID, userId);
   16299             }
   16300             int num = mUserLru.size();
   16301             int i = 0;
   16302             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
   16303                 Integer oldUserId = mUserLru.get(i);
   16304                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
   16305                 if (oldUss == null) {
   16306                     // Shouldn't happen, but be sane if it does.
   16307                     mUserLru.remove(i);
   16308                     num--;
   16309                     continue;
   16310                 }
   16311                 if (oldUss.mState == UserStartedState.STATE_STOPPING
   16312                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
   16313                     // This user is already stopping, doesn't count.
   16314                     num--;
   16315                     i++;
   16316                     continue;
   16317                 }
   16318                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
   16319                     // Owner and current can't be stopped, but count as running.
   16320                     i++;
   16321                     continue;
   16322                 }
   16323                 // This is a user to be stopped.
   16324                 stopUserLocked(oldUserId, null);
   16325                 num--;
   16326                 i++;
   16327             }
   16328         }
   16329     }
   16330 
   16331     @Override
   16332     public int stopUser(final int userId, final IStopUserCallback callback) {
   16333         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16334                 != PackageManager.PERMISSION_GRANTED) {
   16335             String msg = "Permission Denial: switchUser() from pid="
   16336                     + Binder.getCallingPid()
   16337                     + ", uid=" + Binder.getCallingUid()
   16338                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16339             Slog.w(TAG, msg);
   16340             throw new SecurityException(msg);
   16341         }
   16342         if (userId <= 0) {
   16343             throw new IllegalArgumentException("Can't stop primary user " + userId);
   16344         }
   16345         synchronized (this) {
   16346             return stopUserLocked(userId, callback);
   16347         }
   16348     }
   16349 
   16350     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
   16351         if (mCurrentUserId == userId) {
   16352             return ActivityManager.USER_OP_IS_CURRENT;
   16353         }
   16354 
   16355         final UserStartedState uss = mStartedUsers.get(userId);
   16356         if (uss == null) {
   16357             // User is not started, nothing to do...  but we do need to
   16358             // callback if requested.
   16359             if (callback != null) {
   16360                 mHandler.post(new Runnable() {
   16361                     @Override
   16362                     public void run() {
   16363                         try {
   16364                             callback.userStopped(userId);
   16365                         } catch (RemoteException e) {
   16366                         }
   16367                     }
   16368                 });
   16369             }
   16370             return ActivityManager.USER_OP_SUCCESS;
   16371         }
   16372 
   16373         if (callback != null) {
   16374             uss.mStopCallbacks.add(callback);
   16375         }
   16376 
   16377         if (uss.mState != UserStartedState.STATE_STOPPING
   16378                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16379             uss.mState = UserStartedState.STATE_STOPPING;
   16380             updateStartedUserArrayLocked();
   16381 
   16382             long ident = Binder.clearCallingIdentity();
   16383             try {
   16384                 // We are going to broadcast ACTION_USER_STOPPING and then
   16385                 // once that is done send a final ACTION_SHUTDOWN and then
   16386                 // stop the user.
   16387                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
   16388                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   16389                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
   16390                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
   16391                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
   16392                 // This is the result receiver for the final shutdown broadcast.
   16393                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
   16394                     @Override
   16395                     public void performReceive(Intent intent, int resultCode, String data,
   16396                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
   16397                         finishUserStop(uss);
   16398                     }
   16399                 };
   16400                 // This is the result receiver for the initial stopping broadcast.
   16401                 final IIntentReceiver stoppingReceiver = 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                         // On to the next.
   16406                         synchronized (ActivityManagerService.this) {
   16407                             if (uss.mState != UserStartedState.STATE_STOPPING) {
   16408                                 // Whoops, we are being started back up.  Abort, abort!
   16409                                 return;
   16410                             }
   16411                             uss.mState = UserStartedState.STATE_SHUTDOWN;
   16412                         }
   16413                         broadcastIntentLocked(null, null, shutdownIntent,
   16414                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
   16415                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
   16416                     }
   16417                 };
   16418                 // Kick things off.
   16419                 broadcastIntentLocked(null, null, stoppingIntent,
   16420                         null, stoppingReceiver, 0, null, null,
   16421                         android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
   16422                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
   16423             } finally {
   16424                 Binder.restoreCallingIdentity(ident);
   16425             }
   16426         }
   16427 
   16428         return ActivityManager.USER_OP_SUCCESS;
   16429     }
   16430 
   16431     void finishUserStop(UserStartedState uss) {
   16432         final int userId = uss.mHandle.getIdentifier();
   16433         boolean stopped;
   16434         ArrayList<IStopUserCallback> callbacks;
   16435         synchronized (this) {
   16436             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
   16437             if (mStartedUsers.get(userId) != uss) {
   16438                 stopped = false;
   16439             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16440                 stopped = false;
   16441             } else {
   16442                 stopped = true;
   16443                 // User can no longer run.
   16444                 mStartedUsers.remove(userId);
   16445                 mUserLru.remove(Integer.valueOf(userId));
   16446                 updateStartedUserArrayLocked();
   16447 
   16448                 // Clean up all state and processes associated with the user.
   16449                 // Kill all the processes for the user.
   16450                 forceStopUserLocked(userId, "finish user");
   16451             }
   16452         }
   16453 
   16454         for (int i=0; i<callbacks.size(); i++) {
   16455             try {
   16456                 if (stopped) callbacks.get(i).userStopped(userId);
   16457                 else callbacks.get(i).userStopAborted(userId);
   16458             } catch (RemoteException e) {
   16459             }
   16460         }
   16461 
   16462         mStackSupervisor.removeUserLocked(userId);
   16463     }
   16464 
   16465     @Override
   16466     public UserInfo getCurrentUser() {
   16467         if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16468                 != PackageManager.PERMISSION_GRANTED) && (
   16469                 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16470                 != PackageManager.PERMISSION_GRANTED)) {
   16471             String msg = "Permission Denial: getCurrentUser() from pid="
   16472                     + Binder.getCallingPid()
   16473                     + ", uid=" + Binder.getCallingUid()
   16474                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16475             Slog.w(TAG, msg);
   16476             throw new SecurityException(msg);
   16477         }
   16478         synchronized (this) {
   16479             return getUserManagerLocked().getUserInfo(mCurrentUserId);
   16480         }
   16481     }
   16482 
   16483     int getCurrentUserIdLocked() {
   16484         return mCurrentUserId;
   16485     }
   16486 
   16487     @Override
   16488     public boolean isUserRunning(int userId, boolean orStopped) {
   16489         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16490                 != PackageManager.PERMISSION_GRANTED) {
   16491             String msg = "Permission Denial: isUserRunning() from pid="
   16492                     + Binder.getCallingPid()
   16493                     + ", uid=" + Binder.getCallingUid()
   16494                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16495             Slog.w(TAG, msg);
   16496             throw new SecurityException(msg);
   16497         }
   16498         synchronized (this) {
   16499             return isUserRunningLocked(userId, orStopped);
   16500         }
   16501     }
   16502 
   16503     boolean isUserRunningLocked(int userId, boolean orStopped) {
   16504         UserStartedState state = mStartedUsers.get(userId);
   16505         if (state == null) {
   16506             return false;
   16507         }
   16508         if (orStopped) {
   16509             return true;
   16510         }
   16511         return state.mState != UserStartedState.STATE_STOPPING
   16512                 && state.mState != UserStartedState.STATE_SHUTDOWN;
   16513     }
   16514 
   16515     @Override
   16516     public int[] getRunningUserIds() {
   16517         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
   16518                 != PackageManager.PERMISSION_GRANTED) {
   16519             String msg = "Permission Denial: isUserRunning() from pid="
   16520                     + Binder.getCallingPid()
   16521                     + ", uid=" + Binder.getCallingUid()
   16522                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
   16523             Slog.w(TAG, msg);
   16524             throw new SecurityException(msg);
   16525         }
   16526         synchronized (this) {
   16527             return mStartedUserArray;
   16528         }
   16529     }
   16530 
   16531     private void updateStartedUserArrayLocked() {
   16532         int num = 0;
   16533         for (int i=0; i<mStartedUsers.size();  i++) {
   16534             UserStartedState uss = mStartedUsers.valueAt(i);
   16535             // This list does not include stopping users.
   16536             if (uss.mState != UserStartedState.STATE_STOPPING
   16537                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16538                 num++;
   16539             }
   16540         }
   16541         mStartedUserArray = new int[num];
   16542         num = 0;
   16543         for (int i=0; i<mStartedUsers.size();  i++) {
   16544             UserStartedState uss = mStartedUsers.valueAt(i);
   16545             if (uss.mState != UserStartedState.STATE_STOPPING
   16546                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
   16547                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
   16548                 num++;
   16549             }
   16550         }
   16551     }
   16552 
   16553     @Override
   16554     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
   16555         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   16556                 != PackageManager.PERMISSION_GRANTED) {
   16557             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
   16558                     + Binder.getCallingPid()
   16559                     + ", uid=" + Binder.getCallingUid()
   16560                     + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
   16561             Slog.w(TAG, msg);
   16562             throw new SecurityException(msg);
   16563         }
   16564 
   16565         mUserSwitchObservers.register(observer);
   16566     }
   16567 
   16568     @Override
   16569     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
   16570         mUserSwitchObservers.unregister(observer);
   16571     }
   16572 
   16573     private boolean userExists(int userId) {
   16574         if (userId == 0) {
   16575             return true;
   16576         }
   16577         UserManagerService ums = getUserManagerLocked();
   16578         return ums != null ? (ums.getUserInfo(userId) != null) : false;
   16579     }
   16580 
   16581     int[] getUsersLocked() {
   16582         UserManagerService ums = getUserManagerLocked();
   16583         return ums != null ? ums.getUserIds() : new int[] { 0 };
   16584     }
   16585 
   16586     UserManagerService getUserManagerLocked() {
   16587         if (mUserManager == null) {
   16588             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
   16589             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
   16590         }
   16591         return mUserManager;
   16592     }
   16593 
   16594     private int applyUserId(int uid, int userId) {
   16595         return UserHandle.getUid(userId, uid);
   16596     }
   16597 
   16598     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
   16599         if (info == null) return null;
   16600         ApplicationInfo newInfo = new ApplicationInfo(info);
   16601         newInfo.uid = applyUserId(info.uid, userId);
   16602         newInfo.dataDir = USER_DATA_DIR + userId + "/"
   16603                 + info.packageName;
   16604         return newInfo;
   16605     }
   16606 
   16607     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
   16608         if (aInfo == null
   16609                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
   16610             return aInfo;
   16611         }
   16612 
   16613         ActivityInfo info = new ActivityInfo(aInfo);
   16614         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
   16615         return info;
   16616     }
   16617 }
   16618